mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-04 06:10:22 +00:00
fix: checkpoint gate fixes before rebase
This commit is contained in:
@@ -9,12 +9,6 @@ import {
|
||||
type NativeCommandTestParams as RegisterTelegramNativeCommandsParams,
|
||||
} from "./bot-native-commands.fixture-test-support.js";
|
||||
|
||||
const EMPTY_REPLY_COUNTS = {
|
||||
block: 0,
|
||||
final: 0,
|
||||
tool: 0,
|
||||
} as const;
|
||||
|
||||
type RegisteredCommand = {
|
||||
command: string;
|
||||
description: string;
|
||||
@@ -88,17 +82,26 @@ export function createNativeCommandTestParams(
|
||||
cfg: OpenClawConfig,
|
||||
params: Partial<RegisterTelegramNativeCommandsParams> = {},
|
||||
): RegisterTelegramNativeCommandsParams {
|
||||
const dispatchResult: Awaited<
|
||||
ReturnType<TelegramBotDeps["dispatchReplyWithBufferedBlockDispatcher"]>
|
||||
> = {
|
||||
queuedFinal: false,
|
||||
counts: { block: 0, final: 0, tool: 0 },
|
||||
};
|
||||
const telegramDeps: TelegramBotDeps = {
|
||||
loadConfig: vi.fn(() => ({})),
|
||||
resolveStorePath: vi.fn((storePath?: string) => storePath ?? "/tmp/sessions.json"),
|
||||
readChannelAllowFromStore: vi.fn(async () => []),
|
||||
enqueueSystemEvent: vi.fn(),
|
||||
dispatchReplyWithBufferedBlockDispatcher: vi.fn(async () => ({
|
||||
queuedFinal: false,
|
||||
counts: EMPTY_REPLY_COUNTS,
|
||||
})),
|
||||
loadConfig: vi.fn(() => ({}) as OpenClawConfig) as TelegramBotDeps["loadConfig"],
|
||||
resolveStorePath: vi.fn(
|
||||
(storePath?: string) => storePath ?? "/tmp/sessions.json",
|
||||
) as TelegramBotDeps["resolveStorePath"],
|
||||
readChannelAllowFromStore: vi.fn(
|
||||
async () => [],
|
||||
) as TelegramBotDeps["readChannelAllowFromStore"],
|
||||
enqueueSystemEvent: vi.fn() as TelegramBotDeps["enqueueSystemEvent"],
|
||||
dispatchReplyWithBufferedBlockDispatcher: vi.fn(
|
||||
async () => dispatchResult,
|
||||
) as TelegramBotDeps["dispatchReplyWithBufferedBlockDispatcher"],
|
||||
listSkillCommandsForAgents,
|
||||
wasSentByBot: vi.fn(() => false),
|
||||
wasSentByBot: vi.fn(() => false) as TelegramBotDeps["wasSentByBot"],
|
||||
};
|
||||
return createBaseNativeCommandTestParams({
|
||||
cfg,
|
||||
|
||||
@@ -37,27 +37,30 @@ import {
|
||||
waitForRegisteredCommands,
|
||||
} from "./bot-native-commands.menu-test-support.js";
|
||||
|
||||
const EMPTY_REPLY_COUNTS = {
|
||||
block: 0,
|
||||
final: 0,
|
||||
tool: 0,
|
||||
} as const;
|
||||
|
||||
function createNativeCommandTestParams(
|
||||
cfg: OpenClawConfig,
|
||||
params: Partial<Parameters<typeof registerTelegramNativeCommands>[0]> = {},
|
||||
) {
|
||||
const dispatchResult: Awaited<
|
||||
ReturnType<TelegramBotDeps["dispatchReplyWithBufferedBlockDispatcher"]>
|
||||
> = {
|
||||
queuedFinal: false,
|
||||
counts: { block: 0, final: 0, tool: 0 },
|
||||
};
|
||||
const telegramDeps: TelegramBotDeps = {
|
||||
loadConfig: vi.fn(() => ({})),
|
||||
resolveStorePath: vi.fn((storePath?: string) => storePath ?? "/tmp/sessions.json"),
|
||||
readChannelAllowFromStore: vi.fn(async () => []),
|
||||
enqueueSystemEvent: vi.fn(),
|
||||
dispatchReplyWithBufferedBlockDispatcher: vi.fn(async () => ({
|
||||
queuedFinal: false,
|
||||
counts: EMPTY_REPLY_COUNTS,
|
||||
})),
|
||||
loadConfig: vi.fn(() => ({}) as OpenClawConfig) as TelegramBotDeps["loadConfig"],
|
||||
resolveStorePath: vi.fn(
|
||||
(storePath?: string) => storePath ?? "/tmp/sessions.json",
|
||||
) as TelegramBotDeps["resolveStorePath"],
|
||||
readChannelAllowFromStore: vi.fn(
|
||||
async () => [],
|
||||
) as TelegramBotDeps["readChannelAllowFromStore"],
|
||||
enqueueSystemEvent: vi.fn() as TelegramBotDeps["enqueueSystemEvent"],
|
||||
dispatchReplyWithBufferedBlockDispatcher: vi.fn(
|
||||
async () => dispatchResult,
|
||||
) as TelegramBotDeps["dispatchReplyWithBufferedBlockDispatcher"],
|
||||
listSkillCommandsForAgents: skillCommandMocks.listSkillCommandsForAgents,
|
||||
wasSentByBot: vi.fn(() => false),
|
||||
wasSentByBot: vi.fn(() => false) as TelegramBotDeps["wasSentByBot"],
|
||||
};
|
||||
return createNativeCommandTestParamsBase(cfg, {
|
||||
telegramDeps,
|
||||
|
||||
@@ -8,6 +8,11 @@ import type { TelegramBotDeps } from "./bot-deps.js";
|
||||
|
||||
type AnyMock = ReturnType<typeof vi.fn>;
|
||||
type AnyAsyncMock = ReturnType<typeof vi.fn>;
|
||||
type LoadConfigFn = typeof import("openclaw/plugin-sdk/config-runtime").loadConfig;
|
||||
type ResolveStorePathFn = typeof import("openclaw/plugin-sdk/config-runtime").resolveStorePath;
|
||||
type TelegramBotRuntimeForTest = NonNullable<
|
||||
Parameters<typeof import("./bot.js").setTelegramBotRuntimeForTest>[0]
|
||||
>;
|
||||
type DispatchReplyWithBufferedBlockDispatcherFn =
|
||||
typeof import("openclaw/plugin-sdk/reply-runtime").dispatchReplyWithBufferedBlockDispatcher;
|
||||
type DispatchReplyWithBufferedBlockDispatcherResult = Awaited<
|
||||
@@ -37,12 +42,15 @@ vi.doMock("openclaw/plugin-sdk/web-media", () => ({
|
||||
loadWebMedia,
|
||||
}));
|
||||
|
||||
const { loadConfig } = vi.hoisted((): { loadConfig: MockFn<() => OpenClawConfig> } => ({
|
||||
loadConfig: vi.fn(() => ({}) as OpenClawConfig),
|
||||
}));
|
||||
const { resolveStorePathMock } = vi.hoisted(
|
||||
(): { resolveStorePathMock: MockFn<TelegramBotDeps["resolveStorePath"]> } => ({
|
||||
resolveStorePathMock: vi.fn((storePath?: string) => storePath ?? sessionStorePath),
|
||||
const { loadConfig, resolveStorePathMock } = vi.hoisted(
|
||||
(): {
|
||||
loadConfig: MockFn<LoadConfigFn>;
|
||||
resolveStorePathMock: MockFn<ResolveStorePathFn>;
|
||||
} => ({
|
||||
loadConfig: vi.fn<LoadConfigFn>(() => ({})),
|
||||
resolveStorePathMock: vi.fn<ResolveStorePathFn>(
|
||||
(storePath?: string) => storePath ?? sessionStorePath,
|
||||
),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -54,13 +62,6 @@ vi.doMock("openclaw/plugin-sdk/config-runtime", async (importOriginal) => {
|
||||
return {
|
||||
...actual,
|
||||
loadConfig,
|
||||
};
|
||||
});
|
||||
|
||||
vi.doMock("openclaw/plugin-sdk/config-runtime", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/config-runtime")>();
|
||||
return {
|
||||
...actual,
|
||||
resolveStorePath: resolveStorePathMock,
|
||||
};
|
||||
});
|
||||
@@ -95,8 +96,10 @@ vi.doMock("openclaw/plugin-sdk/conversation-runtime", async (importOriginal) =>
|
||||
};
|
||||
});
|
||||
|
||||
const skillCommandsHoisted = vi.hoisted(() => ({
|
||||
const skillCommandListHoisted = vi.hoisted(() => ({
|
||||
listSkillCommandsForAgents: vi.fn(() => []),
|
||||
}));
|
||||
const replySpyHoisted = vi.hoisted(() => ({
|
||||
replySpy: vi.fn(async (_ctx: MsgContext, opts?: GetReplyOptions) => {
|
||||
await opts?.onReplyStart?.();
|
||||
return undefined;
|
||||
@@ -107,36 +110,43 @@ const skillCommandsHoisted = vi.hoisted(() => ({
|
||||
configOverride?: OpenClawConfig,
|
||||
) => Promise<ReplyPayload | ReplyPayload[] | undefined>
|
||||
>,
|
||||
}));
|
||||
const dispatchReplyHoisted = vi.hoisted(() => ({
|
||||
dispatchReplyWithBufferedBlockDispatcher: vi.fn<DispatchReplyWithBufferedBlockDispatcherFn>(
|
||||
async (params: DispatchReplyHarnessParams) => {
|
||||
const result: DispatchReplyWithBufferedBlockDispatcherResult = {
|
||||
queuedFinal: false,
|
||||
counts: EMPTY_REPLY_COUNTS,
|
||||
};
|
||||
await params.dispatcherOptions?.typingCallbacks?.onReplyStart?.();
|
||||
const reply = await skillCommandsHoisted.replySpy(params.ctx, params.replyOptions);
|
||||
const payloads = reply === undefined ? [] : Array.isArray(reply) ? reply : [reply];
|
||||
const reply: ReplyPayload | ReplyPayload[] | undefined = await replySpyHoisted.replySpy(
|
||||
params.ctx,
|
||||
params.replyOptions,
|
||||
);
|
||||
const payloads: ReplyPayload[] =
|
||||
reply === undefined ? [] : Array.isArray(reply) ? reply : [reply];
|
||||
const counts: DispatchReplyWithBufferedBlockDispatcherResult["counts"] = {
|
||||
block: 0,
|
||||
final: payloads.length,
|
||||
tool: 0,
|
||||
};
|
||||
for (const payload of payloads) {
|
||||
await params.dispatcherOptions?.deliver?.(payload, { kind: "final" });
|
||||
}
|
||||
return result;
|
||||
return { queuedFinal: payloads.length > 0, counts };
|
||||
},
|
||||
),
|
||||
}));
|
||||
export const listSkillCommandsForAgents = skillCommandsHoisted.listSkillCommandsForAgents;
|
||||
export const replySpy = skillCommandsHoisted.replySpy;
|
||||
export const listSkillCommandsForAgents = skillCommandListHoisted.listSkillCommandsForAgents;
|
||||
export const replySpy = replySpyHoisted.replySpy;
|
||||
export const dispatchReplyWithBufferedBlockDispatcher =
|
||||
skillCommandsHoisted.dispatchReplyWithBufferedBlockDispatcher;
|
||||
dispatchReplyHoisted.dispatchReplyWithBufferedBlockDispatcher;
|
||||
|
||||
vi.doMock("openclaw/plugin-sdk/reply-runtime", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/reply-runtime")>();
|
||||
return {
|
||||
...actual,
|
||||
listSkillCommandsForAgents: skillCommandsHoisted.listSkillCommandsForAgents,
|
||||
getReplyFromConfig: skillCommandsHoisted.replySpy,
|
||||
__replySpy: skillCommandsHoisted.replySpy,
|
||||
listSkillCommandsForAgents: skillCommandListHoisted.listSkillCommandsForAgents,
|
||||
getReplyFromConfig: replySpyHoisted.replySpy,
|
||||
__replySpy: replySpyHoisted.replySpy,
|
||||
dispatchReplyWithBufferedBlockDispatcher:
|
||||
skillCommandsHoisted.dispatchReplyWithBufferedBlockDispatcher,
|
||||
dispatchReplyHoisted.dispatchReplyWithBufferedBlockDispatcher,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -225,11 +235,7 @@ const runnerHoisted = vi.hoisted(() => ({
|
||||
export const sequentializeSpy: AnyMock = runnerHoisted.sequentializeSpy;
|
||||
export let sequentializeKey: ((ctx: unknown) => string) | undefined;
|
||||
export const throttlerSpy: AnyMock = runnerHoisted.throttlerSpy;
|
||||
export const telegramBotRuntimeForTest: {
|
||||
Bot: new (token: string, options?: { client?: { fetch?: typeof fetch } }) => unknown;
|
||||
sequentialize: (keyFn: (ctx: unknown) => string) => unknown;
|
||||
apiThrottler: () => unknown;
|
||||
} = {
|
||||
export const telegramBotRuntimeForTest: TelegramBotRuntimeForTest = {
|
||||
Bot: class {
|
||||
api = {
|
||||
config: { use: grammySpies.useSpy },
|
||||
@@ -255,23 +261,35 @@ export const telegramBotRuntimeForTest: {
|
||||
public token: string,
|
||||
public options?: { client?: { fetch?: typeof fetch } },
|
||||
) {
|
||||
grammySpies.botCtorSpy(token, options);
|
||||
(grammySpies.botCtorSpy as unknown as (token: string, options?: unknown) => void)(
|
||||
token,
|
||||
options,
|
||||
);
|
||||
}
|
||||
},
|
||||
sequentialize: (keyFn: (ctx: unknown) => string) => {
|
||||
} as unknown as TelegramBotRuntimeForTest["Bot"],
|
||||
sequentialize: ((keyFn: (ctx: unknown) => string) => {
|
||||
sequentializeKey = keyFn;
|
||||
return runnerHoisted.sequentializeSpy();
|
||||
},
|
||||
apiThrottler: () => runnerHoisted.throttlerSpy(),
|
||||
return (
|
||||
runnerHoisted.sequentializeSpy as unknown as () => ReturnType<
|
||||
TelegramBotRuntimeForTest["sequentialize"]
|
||||
>
|
||||
)();
|
||||
}) as unknown as TelegramBotRuntimeForTest["sequentialize"],
|
||||
apiThrottler: (() =>
|
||||
(
|
||||
runnerHoisted.throttlerSpy as unknown as () => unknown
|
||||
)()) as unknown as TelegramBotRuntimeForTest["apiThrottler"],
|
||||
};
|
||||
export const telegramBotDepsForTest: TelegramBotDeps = {
|
||||
loadConfig,
|
||||
resolveStorePath: resolveStorePathMock,
|
||||
readChannelAllowFromStore,
|
||||
enqueueSystemEvent: enqueueSystemEventSpy,
|
||||
readChannelAllowFromStore:
|
||||
readChannelAllowFromStore as TelegramBotDeps["readChannelAllowFromStore"],
|
||||
enqueueSystemEvent: enqueueSystemEventSpy as TelegramBotDeps["enqueueSystemEvent"],
|
||||
dispatchReplyWithBufferedBlockDispatcher,
|
||||
listSkillCommandsForAgents,
|
||||
wasSentByBot,
|
||||
listSkillCommandsForAgents:
|
||||
listSkillCommandsForAgents as TelegramBotDeps["listSkillCommandsForAgents"],
|
||||
wasSentByBot: wasSentByBot as TelegramBotDeps["wasSentByBot"],
|
||||
};
|
||||
|
||||
vi.doMock("./bot.runtime.js", () => telegramBotRuntimeForTest);
|
||||
@@ -361,24 +379,25 @@ beforeEach(() => {
|
||||
stopSpy.mockReset();
|
||||
useSpy.mockReset();
|
||||
replySpy.mockReset();
|
||||
replySpy.mockImplementation(async (_ctx, opts) => {
|
||||
replySpy.mockImplementation(async (_ctx: MsgContext, opts?: GetReplyOptions) => {
|
||||
await opts?.onReplyStart?.();
|
||||
return undefined;
|
||||
});
|
||||
dispatchReplyWithBufferedBlockDispatcher.mockReset();
|
||||
dispatchReplyWithBufferedBlockDispatcher.mockImplementation(
|
||||
async (params: DispatchReplyHarnessParams) => {
|
||||
const result: DispatchReplyWithBufferedBlockDispatcherResult = {
|
||||
queuedFinal: false,
|
||||
counts: EMPTY_REPLY_COUNTS,
|
||||
};
|
||||
await params.dispatcherOptions?.typingCallbacks?.onReplyStart?.();
|
||||
const reply = await replySpy(params.ctx, params.replyOptions);
|
||||
const payloads = reply === undefined ? [] : Array.isArray(reply) ? reply : [reply];
|
||||
const counts: DispatchReplyWithBufferedBlockDispatcherResult["counts"] = {
|
||||
block: 0,
|
||||
final: payloads.length,
|
||||
tool: 0,
|
||||
};
|
||||
for (const payload of payloads) {
|
||||
await params.dispatcherOptions?.deliver?.(payload, { kind: "final" });
|
||||
}
|
||||
return result;
|
||||
return { queuedFinal: payloads.length > 0, counts };
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import type { GetReplyOptions, MsgContext } from "openclaw/plugin-sdk/reply-runtime";
|
||||
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { escapeRegExp, formatEnvelopeTimestamp } from "../../../test/helpers/envelope-timestamp.js";
|
||||
import { withEnvAsync } from "../../../test/helpers/extensions/env.js";
|
||||
@@ -1861,7 +1862,7 @@ describe("createTelegramBot", () => {
|
||||
});
|
||||
it("skips tool summaries for native slash commands", async () => {
|
||||
commandSpy.mockClear();
|
||||
replySpy.mockImplementation(async (_ctx, opts) => {
|
||||
replySpy.mockImplementation(async (_ctx: MsgContext, opts?: GetReplyOptions) => {
|
||||
await opts?.onToolResult?.({ text: "tool update" });
|
||||
return { text: "final reply" };
|
||||
});
|
||||
|
||||
@@ -1,20 +1,25 @@
|
||||
import path from "node:path";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { MediaFetchError } from "openclaw/plugin-sdk/media-runtime";
|
||||
import {
|
||||
resetInboundDedupe,
|
||||
type GetReplyOptions,
|
||||
type MsgContext,
|
||||
type ReplyPayload,
|
||||
} from "openclaw/plugin-sdk/reply-runtime";
|
||||
import { resetInboundDedupe } from "openclaw/plugin-sdk/reply-runtime";
|
||||
import type { GetReplyOptions, MsgContext } from "openclaw/plugin-sdk/reply-runtime";
|
||||
import { beforeEach, vi, type Mock } from "vitest";
|
||||
import type { TelegramBotDeps } from "./bot-deps.js";
|
||||
|
||||
type TelegramBotRuntimeForTest = NonNullable<
|
||||
Parameters<typeof import("./bot.js").setTelegramBotRuntimeForTest>[0]
|
||||
>;
|
||||
type DispatchReplyWithBufferedBlockDispatcherFn =
|
||||
typeof import("openclaw/plugin-sdk/reply-runtime").dispatchReplyWithBufferedBlockDispatcher;
|
||||
type DispatchReplyHarnessParams = Parameters<DispatchReplyWithBufferedBlockDispatcherFn>[0];
|
||||
type FetchRemoteMediaFn = typeof import("openclaw/plugin-sdk/media-runtime").fetchRemoteMedia;
|
||||
|
||||
export const useSpy: Mock = vi.fn();
|
||||
export const middlewareUseSpy: Mock = vi.fn();
|
||||
export const onSpy: Mock = vi.fn();
|
||||
export const stopSpy: Mock = vi.fn();
|
||||
export const sendChatActionSpy: Mock = vi.fn();
|
||||
|
||||
function defaultUndiciFetch(input: RequestInfo | URL, init?: RequestInit) {
|
||||
return globalThis.fetch(input, init);
|
||||
}
|
||||
@@ -26,17 +31,13 @@ export function resetUndiciFetchMock() {
|
||||
undiciFetchSpy.mockImplementation(defaultUndiciFetch);
|
||||
}
|
||||
|
||||
type FetchRemoteMediaFn = typeof import("openclaw/plugin-sdk/media-runtime").fetchRemoteMedia;
|
||||
|
||||
async function defaultFetchRemoteMedia(
|
||||
params: Parameters<FetchRemoteMediaFn>[0],
|
||||
): ReturnType<FetchRemoteMediaFn> {
|
||||
if (!params.fetchImpl) {
|
||||
throw new MediaFetchError("fetch_failed", `Missing fetchImpl for ${params.url}`);
|
||||
}
|
||||
const response = await params.fetchImpl(params.url, {
|
||||
redirect: "manual",
|
||||
});
|
||||
const response = await params.fetchImpl(params.url, { redirect: "manual" });
|
||||
if (!response.ok) {
|
||||
throw new MediaFetchError(
|
||||
"http_error",
|
||||
@@ -104,11 +105,9 @@ const apiStub: ApiStub = {
|
||||
setMyCommands: vi.fn(async () => undefined),
|
||||
};
|
||||
|
||||
export const telegramBotRuntimeForTest: {
|
||||
Bot: new (token: string) => unknown;
|
||||
sequentialize: () => unknown;
|
||||
apiThrottler: () => unknown;
|
||||
} = {
|
||||
const throttlerSpy = vi.fn(() => "throttler");
|
||||
|
||||
export const telegramBotRuntimeForTest: TelegramBotRuntimeForTest = {
|
||||
Bot: class {
|
||||
api = apiStub;
|
||||
use = middlewareUseSpy;
|
||||
@@ -117,67 +116,46 @@ export const telegramBotRuntimeForTest: {
|
||||
stop = stopSpy;
|
||||
catch = vi.fn();
|
||||
constructor(public token: string) {}
|
||||
},
|
||||
sequentialize: () => vi.fn(),
|
||||
apiThrottler: () => throttlerSpy(),
|
||||
} as unknown as TelegramBotRuntimeForTest["Bot"],
|
||||
sequentialize: (() => vi.fn()) as TelegramBotRuntimeForTest["sequentialize"],
|
||||
apiThrottler: (() => throttlerSpy()) as unknown as TelegramBotRuntimeForTest["apiThrottler"],
|
||||
};
|
||||
|
||||
type MediaHarnessReplyFn = (
|
||||
ctx: MsgContext,
|
||||
opts?: GetReplyOptions,
|
||||
configOverride?: OpenClawConfig,
|
||||
) => Promise<ReplyPayload | ReplyPayload[] | undefined>;
|
||||
|
||||
const mediaHarnessReplySpy = vi.hoisted(() => vi.fn<MediaHarnessReplyFn>(async () => undefined));
|
||||
type DispatchReplyWithBufferedBlockDispatcherFn =
|
||||
typeof import("openclaw/plugin-sdk/reply-runtime").dispatchReplyWithBufferedBlockDispatcher;
|
||||
type DispatchReplyHarnessParams = Parameters<DispatchReplyWithBufferedBlockDispatcherFn>[0];
|
||||
|
||||
let actualDispatchReplyWithBufferedBlockDispatcherPromise:
|
||||
| Promise<DispatchReplyWithBufferedBlockDispatcherFn>
|
||||
| undefined;
|
||||
|
||||
async function getActualDispatchReplyWithBufferedBlockDispatcher() {
|
||||
actualDispatchReplyWithBufferedBlockDispatcherPromise ??= vi
|
||||
.importActual<typeof import("openclaw/plugin-sdk/reply-runtime")>(
|
||||
"openclaw/plugin-sdk/reply-runtime",
|
||||
)
|
||||
.then(
|
||||
(module) =>
|
||||
module.dispatchReplyWithBufferedBlockDispatcher as DispatchReplyWithBufferedBlockDispatcherFn,
|
||||
);
|
||||
return await actualDispatchReplyWithBufferedBlockDispatcherPromise;
|
||||
}
|
||||
|
||||
async function dispatchReplyWithBufferedBlockDispatcherViaActual(
|
||||
params: DispatchReplyHarnessParams,
|
||||
) {
|
||||
const actualDispatchReplyWithBufferedBlockDispatcher =
|
||||
await getActualDispatchReplyWithBufferedBlockDispatcher();
|
||||
return await actualDispatchReplyWithBufferedBlockDispatcher({
|
||||
...params,
|
||||
replyResolver: async (ctx, opts, configOverride) => {
|
||||
await opts?.onReplyStart?.();
|
||||
return await mediaHarnessReplySpy(ctx, opts, configOverride as OpenClawConfig | undefined);
|
||||
},
|
||||
});
|
||||
}
|
||||
const mediaHarnessReplySpy = vi.hoisted(() =>
|
||||
vi.fn(async (_ctx: MsgContext, opts?: GetReplyOptions) => {
|
||||
await opts?.onReplyStart?.();
|
||||
return undefined;
|
||||
}),
|
||||
);
|
||||
|
||||
const mediaHarnessDispatchReplyWithBufferedBlockDispatcher = vi.hoisted(() =>
|
||||
vi.fn<DispatchReplyWithBufferedBlockDispatcherFn>(
|
||||
dispatchReplyWithBufferedBlockDispatcherViaActual,
|
||||
),
|
||||
);
|
||||
export const telegramBotDepsForTest: TelegramBotDeps = {
|
||||
loadConfig: () => ({
|
||||
channels: { telegram: { dmPolicy: "open", allowFrom: ["*"] } },
|
||||
vi.fn<DispatchReplyWithBufferedBlockDispatcherFn>(async (params: DispatchReplyHarnessParams) => {
|
||||
await params.dispatcherOptions.typingCallbacks?.onReplyStart?.();
|
||||
const reply = await mediaHarnessReplySpy(params.ctx, params.replyOptions);
|
||||
const payloads = reply === undefined ? [] : Array.isArray(reply) ? reply : [reply];
|
||||
for (const payload of payloads) {
|
||||
await params.dispatcherOptions?.deliver?.(payload, { kind: "final" });
|
||||
}
|
||||
return {
|
||||
queuedFinal: payloads.length > 0,
|
||||
counts: { block: 0, final: payloads.length, tool: 0 },
|
||||
};
|
||||
}),
|
||||
resolveStorePath: vi.fn((storePath?: string) => storePath ?? "/tmp/telegram-media-sessions.json"),
|
||||
readChannelAllowFromStore: vi.fn(async () => [] as string[]),
|
||||
enqueueSystemEvent: vi.fn(),
|
||||
);
|
||||
|
||||
export const telegramBotDepsForTest: TelegramBotDeps = {
|
||||
loadConfig: (() =>
|
||||
({
|
||||
channels: { telegram: { dmPolicy: "open", allowFrom: ["*"] } },
|
||||
}) as OpenClawConfig) as TelegramBotDeps["loadConfig"],
|
||||
resolveStorePath: vi.fn(
|
||||
(storePath?: string) => storePath ?? "/tmp/telegram-media-sessions.json",
|
||||
) as TelegramBotDeps["resolveStorePath"],
|
||||
readChannelAllowFromStore: vi.fn(async () => []) as TelegramBotDeps["readChannelAllowFromStore"],
|
||||
enqueueSystemEvent: vi.fn() as TelegramBotDeps["enqueueSystemEvent"],
|
||||
dispatchReplyWithBufferedBlockDispatcher: mediaHarnessDispatchReplyWithBufferedBlockDispatcher,
|
||||
listSkillCommandsForAgents: vi.fn(() => []),
|
||||
wasSentByBot: vi.fn(() => false),
|
||||
listSkillCommandsForAgents: vi.fn(() => []) as TelegramBotDeps["listSkillCommandsForAgents"],
|
||||
wasSentByBot: vi.fn(() => false) as TelegramBotDeps["wasSentByBot"],
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -187,8 +165,6 @@ beforeEach(() => {
|
||||
resetFetchRemoteMediaMock();
|
||||
});
|
||||
|
||||
const throttlerSpy = vi.fn(() => "throttler");
|
||||
|
||||
vi.doMock("./bot.runtime.js", () => ({
|
||||
...telegramBotRuntimeForTest,
|
||||
}));
|
||||
@@ -224,9 +200,7 @@ vi.doMock("openclaw/plugin-sdk/config-runtime", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/config-runtime")>();
|
||||
return {
|
||||
...actual,
|
||||
loadConfig: () => ({
|
||||
channels: { telegram: { dmPolicy: "open", allowFrom: ["*"] } },
|
||||
}),
|
||||
loadConfig: telegramBotDepsForTest.loadConfig,
|
||||
updateLastRoute: vi.fn(async () => undefined),
|
||||
};
|
||||
});
|
||||
@@ -249,7 +223,7 @@ vi.doMock("openclaw/plugin-sdk/conversation-runtime", async (importOriginal) =>
|
||||
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/conversation-runtime")>();
|
||||
return {
|
||||
...actual,
|
||||
readChannelAllowFromStore: vi.fn(async () => [] as string[]),
|
||||
readChannelAllowFromStore: telegramBotDepsForTest.readChannelAllowFromStore,
|
||||
upsertChannelPairingRequest: vi.fn(async () => ({
|
||||
code: "PAIRCODE",
|
||||
created: true,
|
||||
|
||||
@@ -1067,8 +1067,11 @@ describe("createTelegramBot", () => {
|
||||
expect(replySpy).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
const threadIds = replySpy.mock.calls
|
||||
.map((call) => (call[0] as { MessageThreadId?: number }).MessageThreadId)
|
||||
.toSorted((a, b) => (a ?? 0) - (b ?? 0));
|
||||
.map(
|
||||
(call: [unknown, ...unknown[]]) =>
|
||||
(call[0] as { MessageThreadId?: number }).MessageThreadId,
|
||||
)
|
||||
.toSorted((a: number | undefined, b: number | undefined) => (a ?? 0) - (b ?? 0));
|
||||
expect(threadIds).toEqual([100, 200]);
|
||||
} finally {
|
||||
setTimeoutSpy.mockRestore();
|
||||
|
||||
@@ -9,11 +9,11 @@ import {
|
||||
import { inspectTelegramAccount, type InspectedTelegramAccount } from "../api.js";
|
||||
|
||||
export async function listTelegramDirectoryPeersFromConfig(params: DirectoryConfigParams) {
|
||||
const account = inspectTelegramAccount({
|
||||
const account: InspectedTelegramAccount = inspectTelegramAccount({
|
||||
cfg: params.cfg,
|
||||
accountId: params.accountId,
|
||||
}) as InspectedTelegramAccount | null;
|
||||
if (!account || !("config" in account)) {
|
||||
});
|
||||
if (!account.config) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -34,11 +34,11 @@ export async function listTelegramDirectoryPeersFromConfig(params: DirectoryConf
|
||||
}
|
||||
|
||||
export async function listTelegramDirectoryGroupsFromConfig(params: DirectoryConfigParams) {
|
||||
const account = inspectTelegramAccount({
|
||||
const account: InspectedTelegramAccount = inspectTelegramAccount({
|
||||
cfg: params.cfg,
|
||||
accountId: params.accountId,
|
||||
}) as InspectedTelegramAccount | null;
|
||||
if (!account || !("config" in account)) {
|
||||
});
|
||||
if (!account.config) {
|
||||
return [];
|
||||
}
|
||||
return listDirectoryGroupEntriesFromMapKeys({
|
||||
|
||||
Reference in New Issue
Block a user