mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-04 21:20:22 +00:00
test: merge cron delivery-target thread coverage
This commit is contained in:
committed by
Peter Steinberger
parent
5ff72867bf
commit
6299a5fbfe
@@ -1,182 +0,0 @@
|
||||
import { afterAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { telegramMessagingForTest } from "../infra/outbound/targets.test-helpers.js";
|
||||
|
||||
const mockStore: Record<string, Record<string, unknown>> = {};
|
||||
|
||||
let resolveDeliveryTarget: typeof import("./isolated-agent/delivery-target.js").resolveDeliveryTarget;
|
||||
beforeEach(async () => {
|
||||
vi.resetModules();
|
||||
vi.doMock("../config/sessions/main-session.js", () => ({
|
||||
resolveAgentMainSessionKey: vi.fn(
|
||||
({ agentId }: { agentId: string }) => `agent:${agentId}:main`,
|
||||
),
|
||||
}));
|
||||
vi.doMock("../config/sessions/paths.js", () => ({
|
||||
resolveStorePath: vi.fn((_store: unknown, _opts: unknown) => "/mock/store.json"),
|
||||
}));
|
||||
vi.doMock("../config/sessions/store-load.js", () => ({
|
||||
loadSessionStore: vi.fn((storePath: string) => mockStore[storePath] ?? {}),
|
||||
}));
|
||||
vi.doMock("../infra/outbound/channel-selection.runtime.js", () => ({
|
||||
resolveMessageChannelSelection: vi.fn(async () => ({ channel: "telegram" })),
|
||||
}));
|
||||
vi.doMock("../channels/plugins/index.js", () => ({
|
||||
getChannelPlugin: vi.fn(() => ({
|
||||
meta: { label: "Telegram" },
|
||||
config: {},
|
||||
messaging: telegramMessagingForTest,
|
||||
outbound: {
|
||||
resolveTarget: ({ to }: { to?: string }) =>
|
||||
to ? { ok: true, to } : { ok: false, error: new Error("missing") },
|
||||
},
|
||||
})),
|
||||
normalizeChannelId: vi.fn((id: string) => id),
|
||||
}));
|
||||
({ resolveDeliveryTarget } = await import("./isolated-agent/delivery-target.js"));
|
||||
vi.clearAllMocks();
|
||||
for (const key of Object.keys(mockStore)) {
|
||||
delete mockStore[key];
|
||||
}
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
vi.restoreAllMocks();
|
||||
vi.resetModules();
|
||||
});
|
||||
|
||||
describe("resolveDeliveryTarget thread session lookup", () => {
|
||||
const cfg: OpenClawConfig = {};
|
||||
|
||||
it("uses thread session entry when sessionKey is provided and entry exists", async () => {
|
||||
mockStore["/mock/store.json"] = {
|
||||
"agent:main:main": {
|
||||
sessionId: "s1",
|
||||
updatedAt: 1,
|
||||
lastChannel: "telegram",
|
||||
lastTo: "-100111",
|
||||
},
|
||||
"agent:main:main:thread:9999": {
|
||||
sessionId: "s2",
|
||||
updatedAt: 2,
|
||||
lastChannel: "telegram",
|
||||
lastTo: "-100111",
|
||||
lastThreadId: 9999,
|
||||
},
|
||||
};
|
||||
|
||||
const result = await resolveDeliveryTarget(cfg, "main", {
|
||||
channel: "last",
|
||||
sessionKey: "agent:main:main:thread:9999",
|
||||
});
|
||||
|
||||
expect(result.to).toBe("-100111");
|
||||
expect(result.threadId).toBe(9999);
|
||||
expect(result.channel).toBe("telegram");
|
||||
});
|
||||
|
||||
it("falls back to main session when sessionKey entry does not exist", async () => {
|
||||
mockStore["/mock/store.json"] = {
|
||||
"agent:main:main": {
|
||||
sessionId: "s1",
|
||||
updatedAt: 1,
|
||||
lastChannel: "telegram",
|
||||
lastTo: "-100222",
|
||||
},
|
||||
};
|
||||
|
||||
const result = await resolveDeliveryTarget(cfg, "main", {
|
||||
channel: "last",
|
||||
sessionKey: "agent:main:main:thread:nonexistent",
|
||||
});
|
||||
|
||||
expect(result.to).toBe("-100222");
|
||||
expect(result.threadId).toBeUndefined();
|
||||
expect(result.channel).toBe("telegram");
|
||||
});
|
||||
|
||||
it("falls back to main session when no sessionKey is provided", async () => {
|
||||
mockStore["/mock/store.json"] = {
|
||||
"agent:main:main": {
|
||||
sessionId: "s1",
|
||||
updatedAt: 1,
|
||||
lastChannel: "telegram",
|
||||
lastTo: "-100333",
|
||||
},
|
||||
};
|
||||
|
||||
const result = await resolveDeliveryTarget(cfg, "main", {
|
||||
channel: "last",
|
||||
});
|
||||
|
||||
expect(result.to).toBe("-100333");
|
||||
expect(result.threadId).toBeUndefined();
|
||||
});
|
||||
|
||||
it("preserves threadId from :topic: in delivery.to on first run (no session history)", async () => {
|
||||
mockStore["/mock/store.json"] = {};
|
||||
|
||||
const result = await resolveDeliveryTarget(cfg, "main", {
|
||||
channel: "telegram",
|
||||
to: "63448508:topic:1008013",
|
||||
});
|
||||
|
||||
expect(result.to).toBe("63448508");
|
||||
expect(result.threadId).toBe(1008013);
|
||||
expect(result.channel).toBe("telegram");
|
||||
});
|
||||
|
||||
it("explicit accountId overrides session lastAccountId", async () => {
|
||||
mockStore["/mock/store.json"] = {
|
||||
"agent:main:main": {
|
||||
sessionId: "s1",
|
||||
updatedAt: 1,
|
||||
lastChannel: "telegram",
|
||||
lastTo: "-100444",
|
||||
lastAccountId: "session-account",
|
||||
},
|
||||
};
|
||||
|
||||
const result = await resolveDeliveryTarget(cfg, "main", {
|
||||
channel: "telegram",
|
||||
to: "-100444",
|
||||
accountId: "explicit-account",
|
||||
});
|
||||
|
||||
expect(result.accountId).toBe("explicit-account");
|
||||
expect(result.to).toBe("-100444");
|
||||
});
|
||||
|
||||
it("preserves threadId from :topic: when lastTo differs", async () => {
|
||||
mockStore["/mock/store.json"] = {
|
||||
"agent:main:main": {
|
||||
sessionId: "s1",
|
||||
updatedAt: 1,
|
||||
lastChannel: "telegram",
|
||||
lastTo: "-100999",
|
||||
},
|
||||
};
|
||||
|
||||
const result = await resolveDeliveryTarget(cfg, "main", {
|
||||
channel: "telegram",
|
||||
to: "63448508:topic:1008013",
|
||||
});
|
||||
|
||||
expect(result.to).toBe("63448508");
|
||||
expect(result.threadId).toBe(1008013);
|
||||
});
|
||||
|
||||
it("preserves explicit delivery.threadId on first run without topic syntax", async () => {
|
||||
mockStore["/mock/store.json"] = {};
|
||||
|
||||
const result = await resolveDeliveryTarget(cfg, "main", {
|
||||
channel: "telegram",
|
||||
to: "63448508",
|
||||
threadId: "1008013",
|
||||
});
|
||||
|
||||
expect(result.to).toBe("63448508");
|
||||
expect(result.threadId).toBe("1008013");
|
||||
expect(result.channel).toBe("telegram");
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,7 @@
|
||||
import { afterAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { ChannelOutboundAdapter } from "../../channels/plugins/types.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { telegramMessagingForTest } from "../../infra/outbound/targets.test-helpers.js";
|
||||
import { resetPluginRuntimeStateForTest, setActivePluginRegistry } from "../../plugins/runtime.js";
|
||||
import { createOutboundTestPlugin, createTestRegistry } from "../../test-utils/channel-plugins.js";
|
||||
|
||||
@@ -104,6 +105,7 @@ beforeEach(() => {
|
||||
plugin: createOutboundTestPlugin({
|
||||
id: "telegram",
|
||||
outbound: createStubOutbound("Telegram"),
|
||||
messaging: telegramMessagingForTest,
|
||||
}),
|
||||
source: "test",
|
||||
},
|
||||
@@ -158,9 +160,13 @@ const DEFAULT_TARGET = {
|
||||
|
||||
type SessionStore = ReturnType<typeof loadSessionStore>;
|
||||
|
||||
function setSessionStore(store: SessionStore) {
|
||||
vi.mocked(loadSessionStore).mockReturnValue(store);
|
||||
}
|
||||
|
||||
function setMainSessionEntry(entry?: SessionStore[string]) {
|
||||
const store = entry ? ({ "agent:test:main": entry } as SessionStore) : ({} as SessionStore);
|
||||
vi.mocked(loadSessionStore).mockReturnValue(store);
|
||||
setSessionStore(store);
|
||||
}
|
||||
|
||||
function setLastSessionEntry(params: {
|
||||
@@ -423,7 +429,7 @@ describe("resolveDeliveryTarget", () => {
|
||||
});
|
||||
|
||||
it("uses sessionKey thread entry before main session entry", async () => {
|
||||
vi.mocked(loadSessionStore).mockReturnValue({
|
||||
setSessionStore({
|
||||
"agent:test:main": {
|
||||
sessionId: "main-session",
|
||||
updatedAt: 1000,
|
||||
@@ -435,6 +441,7 @@ describe("resolveDeliveryTarget", () => {
|
||||
updatedAt: 2000,
|
||||
lastChannel: "telegram",
|
||||
lastTo: "thread-chat",
|
||||
lastThreadId: 42,
|
||||
},
|
||||
} as SessionStore);
|
||||
|
||||
@@ -446,6 +453,27 @@ describe("resolveDeliveryTarget", () => {
|
||||
|
||||
expect(result.channel).toBe("telegram");
|
||||
expect(result.to).toBe("thread-chat");
|
||||
expect(result.threadId).toBe(42);
|
||||
});
|
||||
|
||||
it("falls back to the main session entry when the requested sessionKey is missing", async () => {
|
||||
setSessionStore({
|
||||
"agent:test:main": {
|
||||
sessionId: "main-session",
|
||||
updatedAt: 1000,
|
||||
lastChannel: "telegram",
|
||||
lastTo: "main-chat",
|
||||
},
|
||||
} as SessionStore);
|
||||
|
||||
const result = await resolveDeliveryTarget(makeCfg({ bindings: [] }), AGENT_ID, {
|
||||
channel: "last",
|
||||
sessionKey: "agent:test:thread:missing",
|
||||
to: undefined,
|
||||
});
|
||||
|
||||
expect(result.channel).toBe("telegram");
|
||||
expect(result.to).toBe("main-chat");
|
||||
});
|
||||
|
||||
it("uses main session channel when channel=last and session route exists", async () => {
|
||||
@@ -462,6 +490,33 @@ describe("resolveDeliveryTarget", () => {
|
||||
expect(result.ok).toBe(true);
|
||||
});
|
||||
|
||||
it("parses explicit telegram topic targets into delivery threadId", async () => {
|
||||
setMainSessionEntry(undefined);
|
||||
|
||||
const result = await resolveDeliveryTarget(makeCfg({ bindings: [] }), AGENT_ID, {
|
||||
channel: "telegram",
|
||||
to: "63448508:topic:1008013",
|
||||
});
|
||||
|
||||
expect(result.ok).toBe(true);
|
||||
expect(result.to).toBe("63448508");
|
||||
expect(result.threadId).toBe(1008013);
|
||||
});
|
||||
|
||||
it("keeps explicit delivery threadId on first run without session history", async () => {
|
||||
setMainSessionEntry(undefined);
|
||||
|
||||
const result = await resolveDeliveryTarget(makeCfg({ bindings: [] }), AGENT_ID, {
|
||||
channel: "telegram",
|
||||
to: "63448508",
|
||||
threadId: "1008013",
|
||||
});
|
||||
|
||||
expect(result.ok).toBe(true);
|
||||
expect(result.to).toBe("63448508");
|
||||
expect(result.threadId).toBe("1008013");
|
||||
});
|
||||
|
||||
it("explicit delivery.accountId overrides session-derived accountId", async () => {
|
||||
setLastSessionEntry({
|
||||
sessionId: "sess-5",
|
||||
|
||||
Reference in New Issue
Block a user