mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-21 15:01:03 +00:00
* refactor: make OutboundSendDeps dynamic with channel-ID keys
Replace hardcoded per-channel send fields (sendTelegram, sendDiscord,
etc.) with a dynamic index-signature type keyed by channel ID. This
unblocks moving channel implementations to extensions without breaking
the outbound dispatch contract.
- OutboundSendDeps and CliDeps are now { [channelId: string]: unknown }
- Each outbound adapter resolves its send fn via bracket access with cast
- Lazy-loading preserved via createLazySender with module cache
- Delete 6 deps-send-*.runtime.ts one-liner re-export files
- Harden guardrail scan against deleted-but-tracked files
* fix: preserve outbound send-deps compatibility
* style: fix formatting issues (import order, extra bracket, trailing whitespace)
* fix: resolve type errors from dynamic OutboundSendDeps in tests and extension
* fix: remove unused OutboundSendDeps import from deliver.test-helpers
160 lines
3.7 KiB
TypeScript
160 lines
3.7 KiB
TypeScript
import type { OpenClawConfig } from "openclaw/plugin-sdk/matrix";
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
const mocks = vi.hoisted(() => ({
|
|
sendMessageMatrix: vi.fn(),
|
|
sendPollMatrix: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("./matrix/send.js", () => ({
|
|
sendMessageMatrix: mocks.sendMessageMatrix,
|
|
sendPollMatrix: mocks.sendPollMatrix,
|
|
}));
|
|
|
|
vi.mock("./runtime.js", () => ({
|
|
getMatrixRuntime: () => ({
|
|
channel: {
|
|
text: {
|
|
chunkMarkdownText: (text: string) => [text],
|
|
},
|
|
},
|
|
}),
|
|
}));
|
|
|
|
import { matrixOutbound } from "./outbound.js";
|
|
|
|
describe("matrixOutbound cfg threading", () => {
|
|
beforeEach(() => {
|
|
mocks.sendMessageMatrix.mockReset();
|
|
mocks.sendPollMatrix.mockReset();
|
|
mocks.sendMessageMatrix.mockResolvedValue({ messageId: "evt-1", roomId: "!room:example" });
|
|
mocks.sendPollMatrix.mockResolvedValue({ eventId: "$poll", roomId: "!room:example" });
|
|
});
|
|
|
|
it("passes resolved cfg to sendMessageMatrix for text sends", async () => {
|
|
const cfg = {
|
|
channels: {
|
|
matrix: {
|
|
accessToken: "resolved-token",
|
|
},
|
|
},
|
|
} as OpenClawConfig;
|
|
|
|
await matrixOutbound.sendText!({
|
|
cfg,
|
|
to: "room:!room:example",
|
|
text: "hello",
|
|
accountId: "default",
|
|
threadId: "$thread",
|
|
replyToId: "$reply",
|
|
});
|
|
|
|
expect(mocks.sendMessageMatrix).toHaveBeenCalledWith(
|
|
"room:!room:example",
|
|
"hello",
|
|
expect.objectContaining({
|
|
cfg,
|
|
accountId: "default",
|
|
threadId: "$thread",
|
|
replyToId: "$reply",
|
|
}),
|
|
);
|
|
});
|
|
|
|
it("passes resolved cfg to sendMessageMatrix for media sends", async () => {
|
|
const cfg = {
|
|
channels: {
|
|
matrix: {
|
|
accessToken: "resolved-token",
|
|
},
|
|
},
|
|
} as OpenClawConfig;
|
|
|
|
await matrixOutbound.sendMedia!({
|
|
cfg,
|
|
to: "room:!room:example",
|
|
text: "caption",
|
|
mediaUrl: "file:///tmp/cat.png",
|
|
accountId: "default",
|
|
});
|
|
|
|
expect(mocks.sendMessageMatrix).toHaveBeenCalledWith(
|
|
"room:!room:example",
|
|
"caption",
|
|
expect.objectContaining({
|
|
cfg,
|
|
mediaUrl: "file:///tmp/cat.png",
|
|
}),
|
|
);
|
|
});
|
|
|
|
it("passes resolved cfg through injected deps.matrix", async () => {
|
|
const cfg = {
|
|
channels: {
|
|
matrix: {
|
|
accessToken: "resolved-token",
|
|
},
|
|
},
|
|
} as OpenClawConfig;
|
|
const matrix = vi.fn(async () => ({
|
|
messageId: "evt-injected",
|
|
roomId: "!room:example",
|
|
}));
|
|
|
|
await matrixOutbound.sendText!({
|
|
cfg,
|
|
to: "room:!room:example",
|
|
text: "hello via deps",
|
|
deps: { matrix },
|
|
accountId: "default",
|
|
threadId: "$thread",
|
|
replyToId: "$reply",
|
|
});
|
|
|
|
expect(matrix).toHaveBeenCalledWith(
|
|
"room:!room:example",
|
|
"hello via deps",
|
|
expect.objectContaining({
|
|
cfg,
|
|
accountId: "default",
|
|
threadId: "$thread",
|
|
replyToId: "$reply",
|
|
}),
|
|
);
|
|
});
|
|
|
|
it("passes resolved cfg to sendPollMatrix", async () => {
|
|
const cfg = {
|
|
channels: {
|
|
matrix: {
|
|
accessToken: "resolved-token",
|
|
},
|
|
},
|
|
} as OpenClawConfig;
|
|
|
|
await matrixOutbound.sendPoll!({
|
|
cfg,
|
|
to: "room:!room:example",
|
|
poll: {
|
|
question: "Snack?",
|
|
options: ["Pizza", "Sushi"],
|
|
},
|
|
accountId: "default",
|
|
threadId: "$thread",
|
|
});
|
|
|
|
expect(mocks.sendPollMatrix).toHaveBeenCalledWith(
|
|
"room:!room:example",
|
|
expect.objectContaining({
|
|
question: "Snack?",
|
|
options: ["Pizza", "Sushi"],
|
|
}),
|
|
expect.objectContaining({
|
|
cfg,
|
|
accountId: "default",
|
|
threadId: "$thread",
|
|
}),
|
|
);
|
|
});
|
|
});
|