mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-11 14:31:42 +00:00
test(integration): dedupe messaging, secrets, and plugin test suites
This commit is contained in:
@@ -5,23 +5,26 @@ import {
|
||||
type SlackSystemEventTestOverrides,
|
||||
} from "./system-event-test-harness.js";
|
||||
|
||||
const enqueueSystemEventMock = vi.fn();
|
||||
const readAllowFromStoreMock = vi.fn();
|
||||
const messageQueueMock = vi.fn();
|
||||
const messageAllowMock = vi.fn();
|
||||
|
||||
vi.mock("../../../infra/system-events.js", () => ({
|
||||
enqueueSystemEvent: (...args: unknown[]) => enqueueSystemEventMock(...args),
|
||||
enqueueSystemEvent: (...args: unknown[]) => messageQueueMock(...args),
|
||||
}));
|
||||
|
||||
vi.mock("../../../pairing/pairing-store.js", () => ({
|
||||
readChannelAllowFromStore: (...args: unknown[]) => readAllowFromStoreMock(...args),
|
||||
readChannelAllowFromStore: (...args: unknown[]) => messageAllowMock(...args),
|
||||
}));
|
||||
|
||||
type SlackMessageHandler = (args: {
|
||||
event: Record<string, unknown>;
|
||||
body: unknown;
|
||||
}) => Promise<void>;
|
||||
type MessageHandler = (args: { event: Record<string, unknown>; body: unknown }) => Promise<void>;
|
||||
|
||||
function createMessagesContext(overrides?: SlackSystemEventTestOverrides) {
|
||||
type MessageCase = {
|
||||
overrides?: SlackSystemEventTestOverrides;
|
||||
event?: Record<string, unknown>;
|
||||
body?: unknown;
|
||||
};
|
||||
|
||||
function createMessageHandlers(overrides?: SlackSystemEventTestOverrides) {
|
||||
const harness = createSlackSystemEventTestHarness(overrides);
|
||||
const handleSlackMessage = vi.fn(async () => {});
|
||||
registerSlackMessageEvents({
|
||||
@@ -29,7 +32,7 @@ function createMessagesContext(overrides?: SlackSystemEventTestOverrides) {
|
||||
handleSlackMessage,
|
||||
});
|
||||
return {
|
||||
getMessageHandler: () => harness.getHandler("message") as SlackMessageHandler | null,
|
||||
handler: harness.getHandler("message") as MessageHandler | null,
|
||||
handleSlackMessage,
|
||||
};
|
||||
}
|
||||
@@ -40,14 +43,8 @@ function makeChangedEvent(overrides?: { channel?: string; user?: string }) {
|
||||
type: "message",
|
||||
subtype: "message_changed",
|
||||
channel: overrides?.channel ?? "D1",
|
||||
message: {
|
||||
ts: "123.456",
|
||||
user,
|
||||
},
|
||||
previous_message: {
|
||||
ts: "123.450",
|
||||
user,
|
||||
},
|
||||
message: { ts: "123.456", user },
|
||||
previous_message: { ts: "123.450", user },
|
||||
event_ts: "123.456",
|
||||
};
|
||||
}
|
||||
@@ -73,113 +70,78 @@ function makeThreadBroadcastEvent(overrides?: { channel?: string; user?: string
|
||||
subtype: "thread_broadcast",
|
||||
channel: overrides?.channel ?? "D1",
|
||||
user,
|
||||
message: {
|
||||
ts: "123.456",
|
||||
user,
|
||||
},
|
||||
message: { ts: "123.456", user },
|
||||
event_ts: "123.456",
|
||||
};
|
||||
}
|
||||
|
||||
async function runMessageCase(input: MessageCase = {}): Promise<void> {
|
||||
messageQueueMock.mockClear();
|
||||
messageAllowMock.mockReset().mockResolvedValue([]);
|
||||
const { handler } = createMessageHandlers(input.overrides);
|
||||
expect(handler).toBeTruthy();
|
||||
await handler!({
|
||||
event: (input.event ?? makeChangedEvent()) as Record<string, unknown>,
|
||||
body: input.body ?? {},
|
||||
});
|
||||
}
|
||||
|
||||
describe("registerSlackMessageEvents", () => {
|
||||
it("enqueues message_changed system events when dmPolicy is open", async () => {
|
||||
enqueueSystemEventMock.mockClear();
|
||||
readAllowFromStoreMock.mockReset().mockResolvedValue([]);
|
||||
const { getMessageHandler } = createMessagesContext({ dmPolicy: "open" });
|
||||
const messageHandler = getMessageHandler();
|
||||
expect(messageHandler).toBeTruthy();
|
||||
|
||||
await messageHandler!({
|
||||
event: makeChangedEvent(),
|
||||
body: {},
|
||||
});
|
||||
|
||||
expect(enqueueSystemEventMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("blocks message_changed system events when dmPolicy is disabled", async () => {
|
||||
enqueueSystemEventMock.mockClear();
|
||||
readAllowFromStoreMock.mockReset().mockResolvedValue([]);
|
||||
const { getMessageHandler } = createMessagesContext({ dmPolicy: "disabled" });
|
||||
const messageHandler = getMessageHandler();
|
||||
expect(messageHandler).toBeTruthy();
|
||||
|
||||
await messageHandler!({
|
||||
event: makeChangedEvent(),
|
||||
body: {},
|
||||
});
|
||||
|
||||
expect(enqueueSystemEventMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("blocks message_changed system events for unauthorized senders in allowlist mode", async () => {
|
||||
enqueueSystemEventMock.mockClear();
|
||||
readAllowFromStoreMock.mockReset().mockResolvedValue([]);
|
||||
const { getMessageHandler } = createMessagesContext({
|
||||
dmPolicy: "allowlist",
|
||||
allowFrom: ["U2"],
|
||||
});
|
||||
const messageHandler = getMessageHandler();
|
||||
expect(messageHandler).toBeTruthy();
|
||||
|
||||
await messageHandler!({
|
||||
event: makeChangedEvent({ user: "U1" }),
|
||||
body: {},
|
||||
});
|
||||
|
||||
expect(enqueueSystemEventMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("blocks message_deleted system events for users outside channel users allowlist", async () => {
|
||||
enqueueSystemEventMock.mockClear();
|
||||
readAllowFromStoreMock.mockReset().mockResolvedValue([]);
|
||||
const { getMessageHandler } = createMessagesContext({
|
||||
dmPolicy: "open",
|
||||
channelType: "channel",
|
||||
channelUsers: ["U_OWNER"],
|
||||
});
|
||||
const messageHandler = getMessageHandler();
|
||||
expect(messageHandler).toBeTruthy();
|
||||
|
||||
await messageHandler!({
|
||||
event: makeDeletedEvent({ channel: "C1", user: "U_ATTACKER" }),
|
||||
body: {},
|
||||
});
|
||||
|
||||
expect(enqueueSystemEventMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("blocks thread_broadcast system events without an authenticated sender", async () => {
|
||||
enqueueSystemEventMock.mockClear();
|
||||
readAllowFromStoreMock.mockReset().mockResolvedValue([]);
|
||||
const { getMessageHandler } = createMessagesContext({ dmPolicy: "open" });
|
||||
const messageHandler = getMessageHandler();
|
||||
expect(messageHandler).toBeTruthy();
|
||||
|
||||
await messageHandler!({
|
||||
event: {
|
||||
...makeThreadBroadcastEvent(),
|
||||
user: undefined,
|
||||
message: {
|
||||
ts: "123.456",
|
||||
it.each([
|
||||
{
|
||||
name: "enqueues message_changed system events when dmPolicy is open",
|
||||
input: { overrides: { dmPolicy: "open" }, event: makeChangedEvent() },
|
||||
calls: 1,
|
||||
},
|
||||
{
|
||||
name: "blocks message_changed system events when dmPolicy is disabled",
|
||||
input: { overrides: { dmPolicy: "disabled" }, event: makeChangedEvent() },
|
||||
calls: 0,
|
||||
},
|
||||
{
|
||||
name: "blocks message_changed system events for unauthorized senders in allowlist mode",
|
||||
input: {
|
||||
overrides: { dmPolicy: "allowlist", allowFrom: ["U2"] },
|
||||
event: makeChangedEvent({ user: "U1" }),
|
||||
},
|
||||
calls: 0,
|
||||
},
|
||||
{
|
||||
name: "blocks message_deleted system events for users outside channel users allowlist",
|
||||
input: {
|
||||
overrides: {
|
||||
dmPolicy: "open",
|
||||
channelType: "channel",
|
||||
channelUsers: ["U_OWNER"],
|
||||
},
|
||||
event: makeDeletedEvent({ channel: "C1", user: "U_ATTACKER" }),
|
||||
},
|
||||
calls: 0,
|
||||
},
|
||||
{
|
||||
name: "blocks thread_broadcast system events without an authenticated sender",
|
||||
input: {
|
||||
overrides: { dmPolicy: "open" },
|
||||
event: {
|
||||
...makeThreadBroadcastEvent(),
|
||||
user: undefined,
|
||||
message: { ts: "123.456" },
|
||||
},
|
||||
},
|
||||
body: {},
|
||||
});
|
||||
|
||||
expect(enqueueSystemEventMock).not.toHaveBeenCalled();
|
||||
calls: 0,
|
||||
},
|
||||
])("$name", async ({ input, calls }) => {
|
||||
await runMessageCase(input);
|
||||
expect(messageQueueMock).toHaveBeenCalledTimes(calls);
|
||||
});
|
||||
|
||||
it("passes regular message events to the message handler", async () => {
|
||||
enqueueSystemEventMock.mockClear();
|
||||
readAllowFromStoreMock.mockReset().mockResolvedValue([]);
|
||||
const { getMessageHandler, handleSlackMessage } = createMessagesContext({
|
||||
dmPolicy: "open",
|
||||
});
|
||||
const messageHandler = getMessageHandler();
|
||||
expect(messageHandler).toBeTruthy();
|
||||
messageQueueMock.mockClear();
|
||||
messageAllowMock.mockReset().mockResolvedValue([]);
|
||||
const { handler, handleSlackMessage } = createMessageHandlers({ dmPolicy: "open" });
|
||||
expect(handler).toBeTruthy();
|
||||
|
||||
await messageHandler!({
|
||||
await handler!({
|
||||
event: {
|
||||
type: "message",
|
||||
channel: "D1",
|
||||
@@ -191,6 +153,6 @@ describe("registerSlackMessageEvents", () => {
|
||||
});
|
||||
|
||||
expect(handleSlackMessage).toHaveBeenCalledTimes(1);
|
||||
expect(enqueueSystemEventMock).not.toHaveBeenCalled();
|
||||
expect(messageQueueMock).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user