121 lines
3.7 KiB
TypeScript
121 lines
3.7 KiB
TypeScript
// src/tools/file/shell.test.ts
|
|
// Copyright (C) 2025 DTP Technologies, LLC
|
|
// All Rights Reserved
|
|
|
|
import { describe, it, expect, beforeEach } from "vitest";
|
|
import ShellExecTool from "./shell.js";
|
|
|
|
describe("ShellExecTool", () => {
|
|
const tool = ShellExecTool;
|
|
let mockSession: any;
|
|
|
|
beforeEach(() => {
|
|
mockSession = {
|
|
_id: "test-session-id",
|
|
user: "test-user-id",
|
|
};
|
|
});
|
|
|
|
it("should have correct tool definition", () => {
|
|
expect(tool.name).toBe("ShellExecTool");
|
|
expect(tool.slug).toBe("shell-exec");
|
|
expect(tool.definition.type).toBe("function");
|
|
expect(tool.definition.function.name).toBe("shell_exec");
|
|
});
|
|
|
|
it("should have correct metadata", () => {
|
|
expect(tool.metadata.name).toBe("shell_exec");
|
|
expect(tool.metadata.category).toBe("file");
|
|
expect(tool.metadata.tags).toContain("shell");
|
|
});
|
|
|
|
it("should return error for empty command", async () => {
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ command: "" },
|
|
);
|
|
expect(result).toContain("error");
|
|
expect(result).toContain("MISSING_PARAMETER");
|
|
});
|
|
|
|
it("should return error for whitespace-only command", async () => {
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ command: " " },
|
|
);
|
|
expect(result).toContain("error");
|
|
expect(result).toContain("MISSING_PARAMETER");
|
|
});
|
|
|
|
it("should execute simple command successfully", async () => {
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ command: "echo hello" },
|
|
);
|
|
expect(result).toContain("COMMAND: echo hello");
|
|
expect(result).toContain("EXIT CODE: 0");
|
|
expect(result).toContain("---[stdout]");
|
|
expect(result).toContain("hello");
|
|
expect(result).toContain("---[stderr]");
|
|
});
|
|
|
|
it("should return plain text format in message field", async () => {
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ command: "echo test" },
|
|
);
|
|
// The message field should contain plain text format
|
|
expect(result).toContain('"message":');
|
|
// The message should contain plain text headers (not JSON-escaped in the message value)
|
|
expect(result).toContain("COMMAND: echo test");
|
|
expect(result).toContain("EXIT CODE: 0");
|
|
});
|
|
|
|
it("should include stderr when command fails", async () => {
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ command: "ls /nonexistent/path/that/does/not/exist" },
|
|
);
|
|
expect(result).toContain("COMMAND:");
|
|
expect(result).toContain("---[stderr]");
|
|
});
|
|
|
|
it("should handle command with both stdout and stderr", async () => {
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ command: "sh -c 'echo stdout; echo stderr >&2'" },
|
|
);
|
|
expect(result).toContain("---[stdout]");
|
|
expect(result).toContain("---[stderr]");
|
|
expect(result).toContain("stdout");
|
|
expect(result).toContain("stderr");
|
|
});
|
|
|
|
it("should preserve whitespace in output", async () => {
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ command: "echo ' spaces '" },
|
|
);
|
|
// The output should preserve the spaces
|
|
expect(result).toContain("spaces");
|
|
});
|
|
|
|
it("should show N/A for empty stdout", async () => {
|
|
// Commands that produce no stdout
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ command: "true" },
|
|
);
|
|
expect(result).toContain("---[stdout]");
|
|
// Should have the marker even if empty
|
|
});
|
|
|
|
it("should include exit code in output", async () => {
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ command: "echo test" },
|
|
);
|
|
expect(result).toMatch(/EXIT CODE: \d+/);
|
|
});
|
|
});
|