94 lines
2.5 KiB
TypeScript
94 lines
2.5 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { OpenClawConfig } from "../../config/config.js";
|
|
import {
|
|
applyCrossContextDecoration,
|
|
buildCrossContextDecoration,
|
|
enforceCrossContextPolicy,
|
|
} from "./outbound-policy.js";
|
|
|
|
const slackConfig = {
|
|
channels: {
|
|
slack: {
|
|
botToken: "xoxb-test",
|
|
appToken: "xapp-test",
|
|
},
|
|
},
|
|
} as OpenClawConfig;
|
|
|
|
const discordConfig = {
|
|
channels: {
|
|
discord: {},
|
|
},
|
|
} as OpenClawConfig;
|
|
|
|
describe("outbound policy", () => {
|
|
it("blocks cross-provider sends by default", () => {
|
|
expect(() =>
|
|
enforceCrossContextPolicy({
|
|
cfg: slackConfig,
|
|
channel: "telegram",
|
|
action: "send",
|
|
args: { to: "telegram:@ops" },
|
|
toolContext: { currentChannelId: "C12345678", currentChannelProvider: "slack" },
|
|
}),
|
|
).toThrow(/Cross-context messaging denied/);
|
|
});
|
|
|
|
it("allows cross-provider sends when enabled", () => {
|
|
const cfg = {
|
|
...slackConfig,
|
|
tools: {
|
|
message: { crossContext: { allowAcrossProviders: true } },
|
|
},
|
|
} as OpenClawConfig;
|
|
|
|
expect(() =>
|
|
enforceCrossContextPolicy({
|
|
cfg,
|
|
channel: "telegram",
|
|
action: "send",
|
|
args: { to: "telegram:@ops" },
|
|
toolContext: { currentChannelId: "C12345678", currentChannelProvider: "slack" },
|
|
}),
|
|
).not.toThrow();
|
|
});
|
|
|
|
it("blocks same-provider cross-context when disabled", () => {
|
|
const cfg = {
|
|
...slackConfig,
|
|
tools: { message: { crossContext: { allowWithinProvider: false } } },
|
|
} as OpenClawConfig;
|
|
|
|
expect(() =>
|
|
enforceCrossContextPolicy({
|
|
cfg,
|
|
channel: "slack",
|
|
action: "send",
|
|
args: { to: "C99999999" },
|
|
toolContext: { currentChannelId: "C12345678", currentChannelProvider: "slack" },
|
|
}),
|
|
).toThrow(/Cross-context messaging denied/);
|
|
});
|
|
|
|
it("uses components when available and preferred", async () => {
|
|
const decoration = await buildCrossContextDecoration({
|
|
cfg: discordConfig,
|
|
channel: "discord",
|
|
target: "123",
|
|
toolContext: { currentChannelId: "C12345678", currentChannelProvider: "discord" },
|
|
});
|
|
|
|
expect(decoration).not.toBeNull();
|
|
const applied = applyCrossContextDecoration({
|
|
message: "hello",
|
|
decoration: decoration!,
|
|
preferComponents: true,
|
|
});
|
|
|
|
expect(applied.usedComponents).toBe(true);
|
|
expect(applied.componentsBuilder).toBeDefined();
|
|
expect(applied.componentsBuilder?.("hello").length).toBeGreaterThan(0);
|
|
expect(applied.message).toBe("hello");
|
|
});
|
|
});
|