




















@@ -1,5 +1,7 @@
1+import { createHash } from "node:crypto";
12import { buildChannelInboundEventContext } from "openclaw/plugin-sdk/channel-inbound";
23import type { BuildTelegramMessageContextParams, TelegramMediaRef } from "./bot-message-context.js";
4+import { setTelegramTopicNameStoreFactoryForTest } from "./topic-name-cache.js";
3546export const baseTelegramMessageContextConfig = {
57agents: { defaults: { model: "anthropic/claude-opus-4-5", workspace: "/tmp/openclaw" } },
@@ -8,6 +10,13 @@ export const baseTelegramMessageContextConfig = {
810} as never;
9111012type TelegramTestSessionRuntime = NonNullable<BuildTelegramMessageContextParams["sessionRuntime"]>;
13+type TopicNameEntryForTest = {
14+name: string;
15+iconColor?: number;
16+iconCustomEmojiId?: string;
17+closed?: boolean;
18+updatedAt: number;
19+};
11201221type BuildTelegramMessageContextForTestParams = {
1322message: Record<string, unknown>;
@@ -26,28 +35,65 @@ type BuildTelegramMessageContextForTestParams = {
2635resolveTelegramGroupConfig?: BuildTelegramMessageContextParams["resolveTelegramGroupConfig"];
2736};
283729-const telegramMessageContextSessionRuntimeForTest = {
30- buildChannelInboundEventContext,
31-readSessionUpdatedAt: () => undefined,
32-recordInboundSession: async () => undefined,
33-resolveInboundLastRouteSessionKey: ({ route, sessionKey }) =>
34-route.lastRoutePolicy === "main" ? route.mainSessionKey : sessionKey,
35-resolvePinnedMainDmOwnerFromAllowlist: () => null,
36-resolveStorePath: () => "/tmp/openclaw/session-store.json",
37-} satisfies NonNullable<BuildTelegramMessageContextParams["sessionRuntime"]>;
38+const telegramTopicNameStoresForTest = new Map<string, Map<string, TopicNameEntryForTest>>();
39+40+function resolveSessionStorePathForTest(testName: string | undefined): string {
41+const hash = createHash("sha256")
42+.update(`${process.pid}:${testName ?? "unknown"}`)
43+.digest("hex")
44+.slice(0, 16);
45+return `/tmp/openclaw/session-store-${hash}.json`;
46+}
47+48+function createTelegramMessageContextSessionRuntimeForTest(
49+storePath: string,
50+): TelegramTestSessionRuntime {
51+return {
52+ buildChannelInboundEventContext,
53+readSessionUpdatedAt: () => undefined,
54+recordInboundSession: async () => undefined,
55+resolveInboundLastRouteSessionKey: ({ route, sessionKey }) =>
56+route.lastRoutePolicy === "main" ? route.mainSessionKey : sessionKey,
57+resolvePinnedMainDmOwnerFromAllowlist: () => null,
58+resolveStorePath: () => storePath,
59+};
60+}
61+62+function installTelegramTopicNameStoreForTest() {
63+setTelegramTopicNameStoreFactoryForTest((namespace) => {
64+const entries = telegramTopicNameStoresForTest.get(namespace) ?? new Map();
65+telegramTopicNameStoresForTest.set(namespace, entries);
66+return {
67+async register(key, value) {
68+entries.set(key, value);
69+},
70+async entries() {
71+return Array.from(entries, ([key, value]) => ({ key, value }));
72+},
73+async delete(key) {
74+return entries.delete(key);
75+},
76+async clear() {
77+entries.clear();
78+},
79+};
80+});
81+}
38823983export async function buildTelegramMessageContextForTest(
4084params: BuildTelegramMessageContextForTestParams,
4185): Promise<
4286Awaited<ReturnType<typeof import("./bot-message-context.js").buildTelegramMessageContext>>
4387> {
44-const { vi } = await loadVitestModule();
88+const { expect, vi } = await loadVitestModule();
4589const buildTelegramMessageContext = await loadBuildTelegramMessageContext();
4690const sessionRuntime =
4791params.sessionRuntime === null
4892 ? undefined
4993 : {
50- ...telegramMessageContextSessionRuntimeForTest,
94+ ...createTelegramMessageContextSessionRuntimeForTest(
95+resolveSessionStorePathForTest(expect.getState().currentTestName),
96+),
5197 ...params.sessionRuntime,
5298};
5399return await buildTelegramMessageContext({
@@ -119,6 +165,7 @@ async function loadVitestModule() {
119165}
120166121167async function installMessageContextTestMocks() {
168+installTelegramTopicNameStoreForTest();
122169if (messageContextMocksInstalled) {
123170return;
124171}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。