mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-17 04:50:51 +00:00
* refactor: move Telegram channel implementation to extensions/telegram/src/ Move all Telegram channel code (123 files + 10 bot/ files + 8 channel plugin files) from src/telegram/ and src/channels/plugins/*/telegram.ts to extensions/telegram/src/. Leave thin re-export shims at original locations so cross-cutting src/ imports continue to resolve. - Fix all relative import paths in moved files (../X/ -> ../../../src/X/) - Fix vi.mock paths in 60 test files - Fix inline typeof import() expressions - Update tsconfig.plugin-sdk.dts.json rootDir to "." for cross-directory DTS - Update write-plugin-sdk-entry-dts.ts for new rootDir structure - Move channel plugin files with correct path remapping * fix: support keyed telegram send deps * fix: sync telegram extension copies with latest main * fix: correct import paths and remove misplaced files in telegram extension * fix: sync outbound-adapter with main (add sendTelegramPayloadMessages) and fix delivery.test import path
189 lines
5.1 KiB
TypeScript
189 lines
5.1 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import type { OpenClawConfig } from "../../../src/config/config.js";
|
|
|
|
const readConfigFileSnapshotForWrite = vi.fn();
|
|
const writeConfigFile = vi.fn();
|
|
const loadCronStore = vi.fn();
|
|
const resolveCronStorePath = vi.fn();
|
|
const saveCronStore = vi.fn();
|
|
|
|
vi.mock("../../../src/config/config.js", async (importOriginal) => {
|
|
const actual = await importOriginal<typeof import("../../../src/config/config.js")>();
|
|
return {
|
|
...actual,
|
|
readConfigFileSnapshotForWrite,
|
|
writeConfigFile,
|
|
};
|
|
});
|
|
|
|
vi.mock("../../../src/cron/store.js", async (importOriginal) => {
|
|
const actual = await importOriginal<typeof import("../../../src/cron/store.js")>();
|
|
return {
|
|
...actual,
|
|
loadCronStore,
|
|
resolveCronStorePath,
|
|
saveCronStore,
|
|
};
|
|
});
|
|
|
|
const { maybePersistResolvedTelegramTarget } = await import("./target-writeback.js");
|
|
|
|
describe("maybePersistResolvedTelegramTarget", () => {
|
|
beforeEach(() => {
|
|
readConfigFileSnapshotForWrite.mockReset();
|
|
writeConfigFile.mockReset();
|
|
loadCronStore.mockReset();
|
|
resolveCronStorePath.mockReset();
|
|
saveCronStore.mockReset();
|
|
resolveCronStorePath.mockReturnValue("/tmp/cron/jobs.json");
|
|
});
|
|
|
|
it("skips writeback when target is already numeric", async () => {
|
|
await maybePersistResolvedTelegramTarget({
|
|
cfg: {} as OpenClawConfig,
|
|
rawTarget: "-100123",
|
|
resolvedChatId: "-100123",
|
|
});
|
|
|
|
expect(readConfigFileSnapshotForWrite).not.toHaveBeenCalled();
|
|
expect(loadCronStore).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("writes back matching config and cron targets", async () => {
|
|
readConfigFileSnapshotForWrite.mockResolvedValue({
|
|
snapshot: {
|
|
config: {
|
|
channels: {
|
|
telegram: {
|
|
defaultTo: "t.me/mychannel",
|
|
accounts: {
|
|
alerts: {
|
|
defaultTo: "@mychannel",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
writeOptions: { expectedConfigPath: "/tmp/openclaw.json" },
|
|
});
|
|
loadCronStore.mockResolvedValue({
|
|
version: 1,
|
|
jobs: [
|
|
{ id: "a", delivery: { channel: "telegram", to: "https://t.me/mychannel" } },
|
|
{ id: "b", delivery: { channel: "slack", to: "C123" } },
|
|
],
|
|
});
|
|
|
|
await maybePersistResolvedTelegramTarget({
|
|
cfg: {
|
|
cron: { store: "/tmp/cron/jobs.json" },
|
|
} as OpenClawConfig,
|
|
rawTarget: "t.me/mychannel",
|
|
resolvedChatId: "-100123",
|
|
});
|
|
|
|
expect(writeConfigFile).toHaveBeenCalledTimes(1);
|
|
expect(writeConfigFile).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
channels: {
|
|
telegram: {
|
|
defaultTo: "-100123",
|
|
accounts: {
|
|
alerts: {
|
|
defaultTo: "-100123",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
expect.objectContaining({ expectedConfigPath: "/tmp/openclaw.json" }),
|
|
);
|
|
expect(saveCronStore).toHaveBeenCalledTimes(1);
|
|
expect(saveCronStore).toHaveBeenCalledWith(
|
|
"/tmp/cron/jobs.json",
|
|
expect.objectContaining({
|
|
jobs: [
|
|
{ id: "a", delivery: { channel: "telegram", to: "-100123" } },
|
|
{ id: "b", delivery: { channel: "slack", to: "C123" } },
|
|
],
|
|
}),
|
|
);
|
|
});
|
|
|
|
it("preserves topic suffix style in writeback target", async () => {
|
|
readConfigFileSnapshotForWrite.mockResolvedValue({
|
|
snapshot: {
|
|
config: {
|
|
channels: {
|
|
telegram: {
|
|
defaultTo: "t.me/mychannel:topic:9",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
writeOptions: {},
|
|
});
|
|
loadCronStore.mockResolvedValue({ version: 1, jobs: [] });
|
|
|
|
await maybePersistResolvedTelegramTarget({
|
|
cfg: {} as OpenClawConfig,
|
|
rawTarget: "t.me/mychannel:topic:9",
|
|
resolvedChatId: "-100123",
|
|
});
|
|
|
|
expect(writeConfigFile).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
channels: {
|
|
telegram: {
|
|
defaultTo: "-100123:topic:9",
|
|
},
|
|
},
|
|
}),
|
|
expect.any(Object),
|
|
);
|
|
});
|
|
|
|
it("matches username targets case-insensitively", async () => {
|
|
readConfigFileSnapshotForWrite.mockResolvedValue({
|
|
snapshot: {
|
|
config: {
|
|
channels: {
|
|
telegram: {
|
|
defaultTo: "https://t.me/mychannel",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
writeOptions: {},
|
|
});
|
|
loadCronStore.mockResolvedValue({
|
|
version: 1,
|
|
jobs: [{ id: "a", delivery: { channel: "telegram", to: "https://t.me/mychannel" } }],
|
|
});
|
|
|
|
await maybePersistResolvedTelegramTarget({
|
|
cfg: {} as OpenClawConfig,
|
|
rawTarget: "@MyChannel",
|
|
resolvedChatId: "-100123",
|
|
});
|
|
|
|
expect(writeConfigFile).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
channels: {
|
|
telegram: {
|
|
defaultTo: "-100123",
|
|
},
|
|
},
|
|
}),
|
|
expect.any(Object),
|
|
);
|
|
expect(saveCronStore).toHaveBeenCalledWith(
|
|
"/tmp/cron/jobs.json",
|
|
expect.objectContaining({
|
|
jobs: [{ id: "a", delivery: { channel: "telegram", to: "-100123" } }],
|
|
}),
|
|
);
|
|
});
|
|
});
|