Spaces:
Paused
Paused
| import { describe, expect, it } from "vitest"; | |
| import type { DiscordExecApprovalConfig } from "../../config/types.discord.js"; | |
| import { | |
| buildExecApprovalCustomId, | |
| parseExecApprovalData, | |
| type ExecApprovalRequest, | |
| DiscordExecApprovalHandler, | |
| } from "./exec-approvals.js"; | |
| describe("buildExecApprovalCustomId", () => { | |
| it("encodes approval id and action", () => { | |
| const customId = buildExecApprovalCustomId("abc-123", "allow-once"); | |
| expect(customId).toBe("execapproval:id=abc-123;action=allow-once"); | |
| }); | |
| it("encodes special characters in approval id", () => { | |
| const customId = buildExecApprovalCustomId("abc=123;test", "deny"); | |
| expect(customId).toBe("execapproval:id=abc%3D123%3Btest;action=deny"); | |
| }); | |
| }); | |
| describe("parseExecApprovalData", () => { | |
| it("parses valid data", () => { | |
| const result = parseExecApprovalData({ id: "abc-123", action: "allow-once" }); | |
| expect(result).toEqual({ approvalId: "abc-123", action: "allow-once" }); | |
| }); | |
| it("parses encoded data", () => { | |
| const result = parseExecApprovalData({ | |
| id: "abc%3D123%3Btest", | |
| action: "allow-always", | |
| }); | |
| expect(result).toEqual({ approvalId: "abc=123;test", action: "allow-always" }); | |
| }); | |
| it("rejects invalid action", () => { | |
| const result = parseExecApprovalData({ id: "abc-123", action: "invalid" }); | |
| expect(result).toBeNull(); | |
| }); | |
| it("rejects missing id", () => { | |
| const result = parseExecApprovalData({ action: "deny" }); | |
| expect(result).toBeNull(); | |
| }); | |
| it("rejects missing action", () => { | |
| const result = parseExecApprovalData({ id: "abc-123" }); | |
| expect(result).toBeNull(); | |
| }); | |
| it("rejects null/undefined input", () => { | |
| expect(parseExecApprovalData(null as any)).toBeNull(); | |
| expect(parseExecApprovalData(undefined as any)).toBeNull(); | |
| }); | |
| it("accepts all valid actions", () => { | |
| expect(parseExecApprovalData({ id: "x", action: "allow-once" })?.action).toBe("allow-once"); | |
| expect(parseExecApprovalData({ id: "x", action: "allow-always" })?.action).toBe("allow-always"); | |
| expect(parseExecApprovalData({ id: "x", action: "deny" })?.action).toBe("deny"); | |
| }); | |
| }); | |
| describe("roundtrip encoding", () => { | |
| it("encodes and decodes correctly", () => { | |
| const approvalId = "test-approval-with=special;chars&more"; | |
| const action = "allow-always" as const; | |
| const customId = buildExecApprovalCustomId(approvalId, action); | |
| // Parse the key=value pairs from the custom ID | |
| const parts = customId.split(";"); | |
| const data: Record<string, string> = {}; | |
| for (const part of parts) { | |
| const match = part.match(/^([^:]+:)?([^=]+)=(.+)$/); | |
| if (match) { | |
| data[match[2]] = match[3]; | |
| } | |
| } | |
| const result = parseExecApprovalData(data); | |
| expect(result).toEqual({ approvalId, action }); | |
| }); | |
| }); | |
| describe("DiscordExecApprovalHandler.shouldHandle", () => { | |
| function createHandler(config: DiscordExecApprovalConfig) { | |
| return new DiscordExecApprovalHandler({ | |
| token: "test-token", | |
| accountId: "default", | |
| config, | |
| cfg: {}, | |
| }); | |
| } | |
| function createRequest( | |
| overrides: Partial<ExecApprovalRequest["request"]> = {}, | |
| ): ExecApprovalRequest { | |
| return { | |
| id: "test-id", | |
| request: { | |
| command: "echo hello", | |
| cwd: "/home/user", | |
| host: "gateway", | |
| agentId: "test-agent", | |
| sessionKey: "agent:test-agent:discord:123", | |
| ...overrides, | |
| }, | |
| createdAtMs: Date.now(), | |
| expiresAtMs: Date.now() + 60000, | |
| }; | |
| } | |
| it("returns false when disabled", () => { | |
| const handler = createHandler({ enabled: false, approvers: ["123"] }); | |
| expect(handler.shouldHandle(createRequest())).toBe(false); | |
| }); | |
| it("returns false when no approvers", () => { | |
| const handler = createHandler({ enabled: true, approvers: [] }); | |
| expect(handler.shouldHandle(createRequest())).toBe(false); | |
| }); | |
| it("returns true with minimal config", () => { | |
| const handler = createHandler({ enabled: true, approvers: ["123"] }); | |
| expect(handler.shouldHandle(createRequest())).toBe(true); | |
| }); | |
| it("filters by agent ID", () => { | |
| const handler = createHandler({ | |
| enabled: true, | |
| approvers: ["123"], | |
| agentFilter: ["allowed-agent"], | |
| }); | |
| expect(handler.shouldHandle(createRequest({ agentId: "allowed-agent" }))).toBe(true); | |
| expect(handler.shouldHandle(createRequest({ agentId: "other-agent" }))).toBe(false); | |
| expect(handler.shouldHandle(createRequest({ agentId: null }))).toBe(false); | |
| }); | |
| it("filters by session key substring", () => { | |
| const handler = createHandler({ | |
| enabled: true, | |
| approvers: ["123"], | |
| sessionFilter: ["discord"], | |
| }); | |
| expect(handler.shouldHandle(createRequest({ sessionKey: "agent:test:discord:123" }))).toBe( | |
| true, | |
| ); | |
| expect(handler.shouldHandle(createRequest({ sessionKey: "agent:test:telegram:123" }))).toBe( | |
| false, | |
| ); | |
| expect(handler.shouldHandle(createRequest({ sessionKey: null }))).toBe(false); | |
| }); | |
| it("filters by session key regex", () => { | |
| const handler = createHandler({ | |
| enabled: true, | |
| approvers: ["123"], | |
| sessionFilter: ["^agent:.*:discord:"], | |
| }); | |
| expect(handler.shouldHandle(createRequest({ sessionKey: "agent:test:discord:123" }))).toBe( | |
| true, | |
| ); | |
| expect(handler.shouldHandle(createRequest({ sessionKey: "other:test:discord:123" }))).toBe( | |
| false, | |
| ); | |
| }); | |
| it("combines agent and session filters", () => { | |
| const handler = createHandler({ | |
| enabled: true, | |
| approvers: ["123"], | |
| agentFilter: ["my-agent"], | |
| sessionFilter: ["discord"], | |
| }); | |
| expect( | |
| handler.shouldHandle( | |
| createRequest({ | |
| agentId: "my-agent", | |
| sessionKey: "agent:my-agent:discord:123", | |
| }), | |
| ), | |
| ).toBe(true); | |
| expect( | |
| handler.shouldHandle( | |
| createRequest({ | |
| agentId: "other-agent", | |
| sessionKey: "agent:other:discord:123", | |
| }), | |
| ), | |
| ).toBe(false); | |
| expect( | |
| handler.shouldHandle( | |
| createRequest({ | |
| agentId: "my-agent", | |
| sessionKey: "agent:my-agent:telegram:123", | |
| }), | |
| ), | |
| ).toBe(false); | |
| }); | |
| }); | |