test: expand message action helper coverage
This commit is contained in:
@@ -2,15 +2,145 @@ import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { ChannelThreadingToolContext } from "../../channels/plugins/types.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import {
|
||||
hydrateAttachmentParamsForAction,
|
||||
normalizeSandboxMediaList,
|
||||
normalizeSandboxMediaParams,
|
||||
resolveAttachmentMediaPolicy,
|
||||
resolveSlackAutoThreadId,
|
||||
resolveTelegramAutoThreadId,
|
||||
} from "./message-action-params.js";
|
||||
|
||||
const cfg = {} as OpenClawConfig;
|
||||
const maybeIt = process.platform === "win32" ? it.skip : it;
|
||||
|
||||
function createToolContext(
|
||||
overrides: Partial<ChannelThreadingToolContext> = {},
|
||||
): ChannelThreadingToolContext {
|
||||
return {
|
||||
currentChannelId: "C123",
|
||||
currentThreadTs: "thread-1",
|
||||
replyToMode: "all",
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
describe("message action threading helpers", () => {
|
||||
it("resolves Slack auto-thread ids only for matching active channels", () => {
|
||||
expect(
|
||||
resolveSlackAutoThreadId({
|
||||
to: "#c123",
|
||||
toolContext: createToolContext(),
|
||||
}),
|
||||
).toBe("thread-1");
|
||||
expect(
|
||||
resolveSlackAutoThreadId({
|
||||
to: "channel:C999",
|
||||
toolContext: createToolContext(),
|
||||
}),
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
resolveSlackAutoThreadId({
|
||||
to: "user:U123",
|
||||
toolContext: createToolContext(),
|
||||
}),
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
it("skips Slack auto-thread ids when reply mode or context blocks them", () => {
|
||||
expect(
|
||||
resolveSlackAutoThreadId({
|
||||
to: "C123",
|
||||
toolContext: createToolContext({
|
||||
replyToMode: "first",
|
||||
hasRepliedRef: { value: true },
|
||||
}),
|
||||
}),
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
resolveSlackAutoThreadId({
|
||||
to: "C123",
|
||||
toolContext: createToolContext({ replyToMode: "off" }),
|
||||
}),
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
resolveSlackAutoThreadId({
|
||||
to: "C123",
|
||||
toolContext: createToolContext({ currentThreadTs: undefined }),
|
||||
}),
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
it("resolves Telegram auto-thread ids for matching chats across target formats", () => {
|
||||
expect(
|
||||
resolveTelegramAutoThreadId({
|
||||
to: "telegram:group:-100123:topic:77",
|
||||
toolContext: createToolContext({
|
||||
currentChannelId: "tg:group:-100123",
|
||||
}),
|
||||
}),
|
||||
).toBe("thread-1");
|
||||
expect(
|
||||
resolveTelegramAutoThreadId({
|
||||
to: "-100999:77",
|
||||
toolContext: createToolContext({
|
||||
currentChannelId: "-100123",
|
||||
}),
|
||||
}),
|
||||
).toBeUndefined();
|
||||
expect(
|
||||
resolveTelegramAutoThreadId({
|
||||
to: "-100123",
|
||||
toolContext: createToolContext({ currentChannelId: undefined }),
|
||||
}),
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("message action media helpers", () => {
|
||||
it("prefers sandbox media policy when sandbox roots are non-blank", () => {
|
||||
expect(
|
||||
resolveAttachmentMediaPolicy({
|
||||
sandboxRoot: " /tmp/workspace ",
|
||||
mediaLocalRoots: ["/tmp/a"],
|
||||
}),
|
||||
).toEqual({
|
||||
mode: "sandbox",
|
||||
sandboxRoot: "/tmp/workspace",
|
||||
});
|
||||
expect(
|
||||
resolveAttachmentMediaPolicy({
|
||||
sandboxRoot: " ",
|
||||
mediaLocalRoots: ["/tmp/a"],
|
||||
}),
|
||||
).toEqual({
|
||||
mode: "host",
|
||||
localRoots: ["/tmp/a"],
|
||||
});
|
||||
});
|
||||
|
||||
maybeIt("normalizes sandbox media lists and dedupes resolved workspace paths", async () => {
|
||||
const sandboxRoot = await fs.mkdtemp(path.join(os.tmpdir(), "msg-params-list-"));
|
||||
try {
|
||||
await expect(
|
||||
normalizeSandboxMediaList({
|
||||
values: [" data:text/plain;base64,QQ== "],
|
||||
}),
|
||||
).rejects.toThrow(/data:/i);
|
||||
await expect(
|
||||
normalizeSandboxMediaList({
|
||||
values: [" file:///workspace/assets/photo.png ", "/workspace/assets/photo.png", " "],
|
||||
sandboxRoot: ` ${sandboxRoot} `,
|
||||
}),
|
||||
).resolves.toEqual([path.join(sandboxRoot, "assets", "photo.png")]);
|
||||
} finally {
|
||||
await fs.rm(sandboxRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("message action sandbox media hydration", () => {
|
||||
maybeIt("rejects symlink retarget escapes after sandbox media normalization", async () => {
|
||||
const sandboxRoot = await fs.mkdtemp(path.join(os.tmpdir(), "msg-params-sandbox-"));
|
||||
|
||||
Reference in New Issue
Block a user