mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-18 13:30:48 +00:00
* ACPX: keep plugin-local runtime installs out of dist * Gateway: harden ACP startup and service PATH * ACP: reinitialize error-state configured bindings * ACP: classify pre-turn runtime failures as session init failures * Plugins: move configured ACP routing behind channel seams * Telegram tests: align startup probe assertions after rebase * Discord: harden ACP configured binding recovery * ACP: recover Discord bindings after stale runtime exits * ACPX: replace dead sessions during ensure * Discord: harden ACP binding recovery * Discord: fix review follow-ups * ACP bindings: load channel snapshots across workspaces * ACP bindings: cache snapshot channel plugin resolution * Experiments: add ACP pluginification holy grail plan * Experiments: rename ACP pluginification plan doc * Experiments: drop old ACP pluginification doc path * ACP: move configured bindings behind plugin services * Experiments: update bindings capability architecture plan * Bindings: isolate configured binding routing and targets * Discord tests: fix runtime env helper path * Tests: fix channel binding CI regressions * Tests: normalize ACP workspace assertion on Windows * Bindings: isolate configured binding registry * Bindings: finish configured binding cleanup * Bindings: finish generic cleanup * Bindings: align runtime approval callbacks * ACP: delete residual bindings barrel * Bindings: restore legacy compatibility * Revert "Bindings: restore legacy compatibility" This reverts commit ac2ed68fa2426ecc874d68278c71c71ad363fcfe. * Tests: drop ACP route legacy helper names * Discord/ACP: fix binding regressions --------- Co-authored-by: Onur <2453968+osolmaz@users.noreply.github.com>
184 lines
5.1 KiB
TypeScript
184 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("openclaw/plugin-sdk/config-runtime", async (importOriginal) => {
|
|
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/config-runtime")>();
|
|
return {
|
|
...actual,
|
|
readConfigFileSnapshotForWrite,
|
|
writeConfigFile,
|
|
loadCronStore,
|
|
resolveCronStorePath,
|
|
saveCronStore,
|
|
};
|
|
});
|
|
|
|
describe("maybePersistResolvedTelegramTarget", () => {
|
|
let maybePersistResolvedTelegramTarget: typeof import("./target-writeback.js").maybePersistResolvedTelegramTarget;
|
|
|
|
beforeEach(async () => {
|
|
vi.resetModules();
|
|
({ maybePersistResolvedTelegramTarget } = await import("./target-writeback.js"));
|
|
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" } }],
|
|
}),
|
|
);
|
|
});
|
|
});
|