mirror of
https://github.com/farcasclaudiu/openclaw.git
synced 2026-06-28 23:02:02 +03:00
refactor(test): dedupe slack inbound contract prep
This commit is contained in:
@@ -14,6 +14,67 @@ import { createSlackMonitorContext } from "../context.js";
|
|||||||
import { prepareSlackMessage } from "./prepare.js";
|
import { prepareSlackMessage } from "./prepare.js";
|
||||||
|
|
||||||
describe("slack prepareSlackMessage inbound contract", () => {
|
describe("slack prepareSlackMessage inbound contract", () => {
|
||||||
|
function createDefaultSlackCtx() {
|
||||||
|
const slackCtx = createSlackMonitorContext({
|
||||||
|
cfg: {
|
||||||
|
channels: { slack: { enabled: true } },
|
||||||
|
} as OpenClawConfig,
|
||||||
|
accountId: "default",
|
||||||
|
botToken: "token",
|
||||||
|
app: { client: {} } as App,
|
||||||
|
runtime: {} as RuntimeEnv,
|
||||||
|
botUserId: "B1",
|
||||||
|
teamId: "T1",
|
||||||
|
apiAppId: "A1",
|
||||||
|
historyLimit: 0,
|
||||||
|
sessionScope: "per-sender",
|
||||||
|
mainKey: "main",
|
||||||
|
dmEnabled: true,
|
||||||
|
dmPolicy: "open",
|
||||||
|
allowFrom: [],
|
||||||
|
groupDmEnabled: true,
|
||||||
|
groupDmChannels: [],
|
||||||
|
defaultRequireMention: true,
|
||||||
|
groupPolicy: "open",
|
||||||
|
useAccessGroups: false,
|
||||||
|
reactionMode: "off",
|
||||||
|
reactionAllowlist: [],
|
||||||
|
replyToMode: "off",
|
||||||
|
threadHistoryScope: "thread",
|
||||||
|
threadInheritParent: false,
|
||||||
|
slashCommand: {
|
||||||
|
enabled: false,
|
||||||
|
name: "openclaw",
|
||||||
|
sessionPrefix: "slack:slash",
|
||||||
|
ephemeral: true,
|
||||||
|
},
|
||||||
|
textLimit: 4000,
|
||||||
|
ackReactionScope: "group-mentions",
|
||||||
|
mediaMaxBytes: 1024,
|
||||||
|
removeAckAfterReply: false,
|
||||||
|
});
|
||||||
|
// oxlint-disable-next-line typescript/no-explicit-any
|
||||||
|
slackCtx.resolveUserName = async () => ({ name: "Alice" }) as any;
|
||||||
|
return slackCtx;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultAccount: ResolvedSlackAccount = {
|
||||||
|
accountId: "default",
|
||||||
|
enabled: true,
|
||||||
|
botTokenSource: "config",
|
||||||
|
appTokenSource: "config",
|
||||||
|
config: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
async function prepareWithDefaultCtx(message: SlackMessageEvent) {
|
||||||
|
return prepareSlackMessage({
|
||||||
|
ctx: createDefaultSlackCtx(),
|
||||||
|
account: defaultAccount,
|
||||||
|
message,
|
||||||
|
opts: { source: "message" },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
it("produces a finalized MsgContext", async () => {
|
it("produces a finalized MsgContext", async () => {
|
||||||
const slackCtx = createSlackMonitorContext({
|
const slackCtx = createSlackMonitorContext({
|
||||||
cfg: {
|
cfg: {
|
||||||
@@ -443,55 +504,6 @@ describe("slack prepareSlackMessage inbound contract", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("includes thread_ts and parent_user_id metadata in thread replies", async () => {
|
it("includes thread_ts and parent_user_id metadata in thread replies", async () => {
|
||||||
const slackCtx = createSlackMonitorContext({
|
|
||||||
cfg: {
|
|
||||||
channels: { slack: { enabled: true } },
|
|
||||||
} as OpenClawConfig,
|
|
||||||
accountId: "default",
|
|
||||||
botToken: "token",
|
|
||||||
app: { client: {} } as App,
|
|
||||||
runtime: {} as RuntimeEnv,
|
|
||||||
botUserId: "B1",
|
|
||||||
teamId: "T1",
|
|
||||||
apiAppId: "A1",
|
|
||||||
historyLimit: 0,
|
|
||||||
sessionScope: "per-sender",
|
|
||||||
mainKey: "main",
|
|
||||||
dmEnabled: true,
|
|
||||||
dmPolicy: "open",
|
|
||||||
allowFrom: [],
|
|
||||||
groupDmEnabled: true,
|
|
||||||
groupDmChannels: [],
|
|
||||||
defaultRequireMention: true,
|
|
||||||
groupPolicy: "open",
|
|
||||||
useAccessGroups: false,
|
|
||||||
reactionMode: "off",
|
|
||||||
reactionAllowlist: [],
|
|
||||||
replyToMode: "off",
|
|
||||||
threadHistoryScope: "thread",
|
|
||||||
threadInheritParent: false,
|
|
||||||
slashCommand: {
|
|
||||||
enabled: false,
|
|
||||||
name: "openclaw",
|
|
||||||
sessionPrefix: "slack:slash",
|
|
||||||
ephemeral: true,
|
|
||||||
},
|
|
||||||
textLimit: 4000,
|
|
||||||
ackReactionScope: "group-mentions",
|
|
||||||
mediaMaxBytes: 1024,
|
|
||||||
removeAckAfterReply: false,
|
|
||||||
});
|
|
||||||
// oxlint-disable-next-line typescript/no-explicit-any
|
|
||||||
slackCtx.resolveUserName = async () => ({ name: "Alice" }) as any;
|
|
||||||
|
|
||||||
const account: ResolvedSlackAccount = {
|
|
||||||
accountId: "default",
|
|
||||||
enabled: true,
|
|
||||||
botTokenSource: "config",
|
|
||||||
appTokenSource: "config",
|
|
||||||
config: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
const message: SlackMessageEvent = {
|
const message: SlackMessageEvent = {
|
||||||
channel: "D123",
|
channel: "D123",
|
||||||
channel_type: "im",
|
channel_type: "im",
|
||||||
@@ -502,12 +514,7 @@ describe("slack prepareSlackMessage inbound contract", () => {
|
|||||||
parent_user_id: "U2",
|
parent_user_id: "U2",
|
||||||
} as SlackMessageEvent;
|
} as SlackMessageEvent;
|
||||||
|
|
||||||
const prepared = await prepareSlackMessage({
|
const prepared = await prepareWithDefaultCtx(message);
|
||||||
ctx: slackCtx,
|
|
||||||
account,
|
|
||||||
message,
|
|
||||||
opts: { source: "message" },
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(prepared).toBeTruthy();
|
expect(prepared).toBeTruthy();
|
||||||
// Verify thread metadata is in the message footer
|
// Verify thread metadata is in the message footer
|
||||||
@@ -517,55 +524,6 @@ describe("slack prepareSlackMessage inbound contract", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("excludes thread_ts from top-level messages", async () => {
|
it("excludes thread_ts from top-level messages", async () => {
|
||||||
const slackCtx = createSlackMonitorContext({
|
|
||||||
cfg: {
|
|
||||||
channels: { slack: { enabled: true } },
|
|
||||||
} as OpenClawConfig,
|
|
||||||
accountId: "default",
|
|
||||||
botToken: "token",
|
|
||||||
app: { client: {} } as App,
|
|
||||||
runtime: {} as RuntimeEnv,
|
|
||||||
botUserId: "B1",
|
|
||||||
teamId: "T1",
|
|
||||||
apiAppId: "A1",
|
|
||||||
historyLimit: 0,
|
|
||||||
sessionScope: "per-sender",
|
|
||||||
mainKey: "main",
|
|
||||||
dmEnabled: true,
|
|
||||||
dmPolicy: "open",
|
|
||||||
allowFrom: [],
|
|
||||||
groupDmEnabled: true,
|
|
||||||
groupDmChannels: [],
|
|
||||||
defaultRequireMention: true,
|
|
||||||
groupPolicy: "open",
|
|
||||||
useAccessGroups: false,
|
|
||||||
reactionMode: "off",
|
|
||||||
reactionAllowlist: [],
|
|
||||||
replyToMode: "off",
|
|
||||||
threadHistoryScope: "thread",
|
|
||||||
threadInheritParent: false,
|
|
||||||
slashCommand: {
|
|
||||||
enabled: false,
|
|
||||||
name: "openclaw",
|
|
||||||
sessionPrefix: "slack:slash",
|
|
||||||
ephemeral: true,
|
|
||||||
},
|
|
||||||
textLimit: 4000,
|
|
||||||
ackReactionScope: "group-mentions",
|
|
||||||
mediaMaxBytes: 1024,
|
|
||||||
removeAckAfterReply: false,
|
|
||||||
});
|
|
||||||
// oxlint-disable-next-line typescript/no-explicit-any
|
|
||||||
slackCtx.resolveUserName = async () => ({ name: "Alice" }) as any;
|
|
||||||
|
|
||||||
const account: ResolvedSlackAccount = {
|
|
||||||
accountId: "default",
|
|
||||||
enabled: true,
|
|
||||||
botTokenSource: "config",
|
|
||||||
appTokenSource: "config",
|
|
||||||
config: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
const message: SlackMessageEvent = {
|
const message: SlackMessageEvent = {
|
||||||
channel: "D123",
|
channel: "D123",
|
||||||
channel_type: "im",
|
channel_type: "im",
|
||||||
@@ -574,12 +532,7 @@ describe("slack prepareSlackMessage inbound contract", () => {
|
|||||||
ts: "1.000",
|
ts: "1.000",
|
||||||
} as SlackMessageEvent;
|
} as SlackMessageEvent;
|
||||||
|
|
||||||
const prepared = await prepareSlackMessage({
|
const prepared = await prepareWithDefaultCtx(message);
|
||||||
ctx: slackCtx,
|
|
||||||
account,
|
|
||||||
message,
|
|
||||||
opts: { source: "message" },
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(prepared).toBeTruthy();
|
expect(prepared).toBeTruthy();
|
||||||
// Top-level messages should NOT have thread_ts in the footer
|
// Top-level messages should NOT have thread_ts in the footer
|
||||||
@@ -588,55 +541,6 @@ describe("slack prepareSlackMessage inbound contract", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("excludes thread metadata when thread_ts equals ts without parent_user_id", async () => {
|
it("excludes thread metadata when thread_ts equals ts without parent_user_id", async () => {
|
||||||
const slackCtx = createSlackMonitorContext({
|
|
||||||
cfg: {
|
|
||||||
channels: { slack: { enabled: true } },
|
|
||||||
} as OpenClawConfig,
|
|
||||||
accountId: "default",
|
|
||||||
botToken: "token",
|
|
||||||
app: { client: {} } as App,
|
|
||||||
runtime: {} as RuntimeEnv,
|
|
||||||
botUserId: "B1",
|
|
||||||
teamId: "T1",
|
|
||||||
apiAppId: "A1",
|
|
||||||
historyLimit: 0,
|
|
||||||
sessionScope: "per-sender",
|
|
||||||
mainKey: "main",
|
|
||||||
dmEnabled: true,
|
|
||||||
dmPolicy: "open",
|
|
||||||
allowFrom: [],
|
|
||||||
groupDmEnabled: true,
|
|
||||||
groupDmChannels: [],
|
|
||||||
defaultRequireMention: true,
|
|
||||||
groupPolicy: "open",
|
|
||||||
useAccessGroups: false,
|
|
||||||
reactionMode: "off",
|
|
||||||
reactionAllowlist: [],
|
|
||||||
replyToMode: "off",
|
|
||||||
threadHistoryScope: "thread",
|
|
||||||
threadInheritParent: false,
|
|
||||||
slashCommand: {
|
|
||||||
enabled: false,
|
|
||||||
name: "openclaw",
|
|
||||||
sessionPrefix: "slack:slash",
|
|
||||||
ephemeral: true,
|
|
||||||
},
|
|
||||||
textLimit: 4000,
|
|
||||||
ackReactionScope: "group-mentions",
|
|
||||||
mediaMaxBytes: 1024,
|
|
||||||
removeAckAfterReply: false,
|
|
||||||
});
|
|
||||||
// oxlint-disable-next-line typescript/no-explicit-any
|
|
||||||
slackCtx.resolveUserName = async () => ({ name: "Alice" }) as any;
|
|
||||||
|
|
||||||
const account: ResolvedSlackAccount = {
|
|
||||||
accountId: "default",
|
|
||||||
enabled: true,
|
|
||||||
botTokenSource: "config",
|
|
||||||
appTokenSource: "config",
|
|
||||||
config: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
const message: SlackMessageEvent = {
|
const message: SlackMessageEvent = {
|
||||||
channel: "D123",
|
channel: "D123",
|
||||||
channel_type: "im",
|
channel_type: "im",
|
||||||
@@ -646,12 +550,7 @@ describe("slack prepareSlackMessage inbound contract", () => {
|
|||||||
thread_ts: "1.000",
|
thread_ts: "1.000",
|
||||||
} as SlackMessageEvent;
|
} as SlackMessageEvent;
|
||||||
|
|
||||||
const prepared = await prepareSlackMessage({
|
const prepared = await prepareWithDefaultCtx(message);
|
||||||
ctx: slackCtx,
|
|
||||||
account,
|
|
||||||
message,
|
|
||||||
opts: { source: "message" },
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(prepared).toBeTruthy();
|
expect(prepared).toBeTruthy();
|
||||||
expect(prepared!.ctxPayload.Body).toMatch(/\[slack message id: 1\.000 channel: D123\]$/);
|
expect(prepared!.ctxPayload.Body).toMatch(/\[slack message id: 1\.000 channel: D123\]$/);
|
||||||
|
|||||||
Reference in New Issue
Block a user