mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 08:58:37 +00:00
fix(mattermost): harden react remove flag parsing
This commit is contained in:
@@ -187,6 +187,58 @@ describe("mattermostPlugin", () => {
|
|||||||
(globalThis as any).fetch = prevFetch;
|
(globalThis as any).fetch = prevFetch;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("only treats boolean remove flag as removal", async () => {
|
||||||
|
const cfg: OpenClawConfig = {
|
||||||
|
channels: {
|
||||||
|
mattermost: {
|
||||||
|
enabled: true,
|
||||||
|
botToken: "test-token",
|
||||||
|
baseUrl: "https://chat.example.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchImpl = vi.fn(async (url: any, init?: any) => {
|
||||||
|
if (String(url).endsWith("/api/v4/users/me")) {
|
||||||
|
return new Response(JSON.stringify({ id: "BOT123" }), {
|
||||||
|
status: 200,
|
||||||
|
headers: { "content-type": "application/json" },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (String(url).endsWith("/api/v4/reactions")) {
|
||||||
|
expect(init?.method).toBe("POST");
|
||||||
|
expect(JSON.parse(init?.body)).toEqual({
|
||||||
|
user_id: "BOT123",
|
||||||
|
post_id: "POST1",
|
||||||
|
emoji_name: "thumbsup",
|
||||||
|
});
|
||||||
|
return new Response(JSON.stringify({ ok: true }), {
|
||||||
|
status: 201,
|
||||||
|
headers: { "content-type": "application/json" },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
throw new Error(`unexpected url: ${url}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
const prevFetch = globalThis.fetch;
|
||||||
|
(globalThis as any).fetch = fetchImpl;
|
||||||
|
try {
|
||||||
|
const result = await mattermostPlugin.actions?.handleAction?.({
|
||||||
|
channel: "mattermost",
|
||||||
|
action: "react",
|
||||||
|
params: { messageId: "POST1", emoji: "thumbsup", remove: "true" },
|
||||||
|
cfg,
|
||||||
|
accountId: "default",
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
expect(result?.content).toEqual([
|
||||||
|
{ type: "text", text: "Reacted with :thumbsup: on POST1" },
|
||||||
|
]);
|
||||||
|
} finally {
|
||||||
|
(globalThis as any).fetch = prevFetch;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("config", () => {
|
describe("config", () => {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ const mattermostMessageActions: ChannelMessageActionAdapter = {
|
|||||||
throw new Error("Mattermost react requires emoji");
|
throw new Error("Mattermost react requires emoji");
|
||||||
}
|
}
|
||||||
|
|
||||||
const remove = Boolean((params as any)?.remove);
|
const remove = (params as any)?.remove === true;
|
||||||
if (remove) {
|
if (remove) {
|
||||||
const result = await removeMattermostReaction({
|
const result = await removeMattermostReaction({
|
||||||
cfg,
|
cfg,
|
||||||
|
|||||||
@@ -170,4 +170,60 @@ describe("mattermost websocket monitor", () => {
|
|||||||
expect(patches.some((patch) => patch.connected === true)).toBe(true);
|
expect(patches.some((patch) => patch.connected === true)).toBe(true);
|
||||||
expect(patches.filter((patch) => patch.connected === false)).toHaveLength(2);
|
expect(patches.filter((patch) => patch.connected === false)).toHaveLength(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("dispatches reaction events to the reaction handler", async () => {
|
||||||
|
const socket = new FakeWebSocket();
|
||||||
|
const onPosted = vi.fn(async () => {});
|
||||||
|
const onReaction = vi.fn(async (payload) => payload);
|
||||||
|
const connectOnce = createMattermostConnectOnce({
|
||||||
|
wsUrl: "wss://example.invalid/api/v4/websocket",
|
||||||
|
botToken: "token",
|
||||||
|
runtime: testRuntime(),
|
||||||
|
nextSeq: () => 1,
|
||||||
|
onPosted,
|
||||||
|
onReaction,
|
||||||
|
webSocketFactory: () => socket,
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.emitOpen();
|
||||||
|
socket.emitMessage(
|
||||||
|
Buffer.from(
|
||||||
|
JSON.stringify({
|
||||||
|
event: "reaction_added",
|
||||||
|
data: {
|
||||||
|
reaction: JSON.stringify({
|
||||||
|
user_id: "user-1",
|
||||||
|
post_id: "post-1",
|
||||||
|
emoji_name: "thumbsup",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
socket.emitClose(1000);
|
||||||
|
|
||||||
|
await connectOnce();
|
||||||
|
|
||||||
|
expect(onReaction).toHaveBeenCalledTimes(1);
|
||||||
|
expect(onPosted).not.toHaveBeenCalled();
|
||||||
|
const payload = onReaction.mock.calls[0]?.[0];
|
||||||
|
expect(payload).toMatchObject({
|
||||||
|
event: "reaction_added",
|
||||||
|
data: {
|
||||||
|
reaction: JSON.stringify({
|
||||||
|
user_id: "user-1",
|
||||||
|
post_id: "post-1",
|
||||||
|
emoji_name: "thumbsup",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(payload.data?.reaction).toBe(
|
||||||
|
JSON.stringify({
|
||||||
|
user_id: "user-1",
|
||||||
|
post_id: "post-1",
|
||||||
|
emoji_name: "thumbsup",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
expect(payload.data?.reaction).toBeDefined();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user