gadget/docs/archive/tools/file/write.test.ts

155 lines
4.8 KiB
TypeScript

// src/tools/file/write.test.ts
// Copyright (C) 2025 DTP Technologies, LLC
// All Rights Reserved
import { describe, it, expect, beforeEach, afterEach } from "vitest";
import { FileWriteTool } from "./write.js";
import fs from "node:fs/promises";
import path from "node:path";
import { PROJECT_ROOT } from "../../config/env.js";
const tool = new FileWriteTool();
describe("FileWriteTool", () => {
const testDir = path.join(PROJECT_ROOT, "test-temp-write");
const testFile = path.join(testDir, "test.txt");
beforeEach(async () => {
await fs.mkdir(testDir, { recursive: true });
});
afterEach(async () => {
await fs.rm(testDir, { recursive: true, force: true });
});
it("should have correct tool definition", () => {
expect(tool.definition.function.name).toBe("file_write");
expect(tool.definition.function.description).toContain(
"Create a new file or overwrite",
);
const params = tool.definition.function.parameters as any;
expect(params.required).toEqual(["path", "content"]);
});
it("should reject empty path", async () => {
const result = await tool.execute({} as any, { content: "test" });
expect(result).toContain("error");
expect(result).toContain("MISSING_PARAMETER");
});
it("should reject undefined content", async () => {
const result = await tool.execute({} as any, { path: "test.txt" });
expect(result).toContain("error");
expect(result).toContain("MISSING_PARAMETER");
});
it("should reject path traversal attempts", async () => {
const result = await tool.execute({} as any, {
path: "../../../etc/passwd",
content: "test",
});
expect(result).toContain("error");
expect(result).toContain("SECURITY_VIOLATION");
});
it("should create new file and return plain text response", async () => {
const result = await tool.execute({} as any, {
path: "test-temp-write/test.txt",
content: "Hello, World!",
});
expect(result).not.toContain('"success"');
expect(result).toContain("PATH:");
expect(result).toContain("FILE OPERATION: write");
expect(result).toContain("CREATED: true");
expect(result).toContain("BYTES WRITTEN:");
expect(result).toContain("---");
expect(result).toContain("File written:");
});
it("should overwrite existing file and return plain text response", async () => {
// Create file first
await fs.writeFile(testFile, "original content");
const result = await tool.execute({} as any, {
path: "test-temp-write/test.txt",
content: "new content",
});
expect(result).not.toContain('"success"');
expect(result).toContain("PATH:");
expect(result).toContain("FILE OPERATION: write");
expect(result).toContain("CREATED: false");
expect(result).toContain("BYTES WRITTEN:");
expect(result).toContain("---");
});
it("should create parent directories automatically", async () => {
const nestedPath = "test-temp-write/nested/deep/file.txt";
const result = await tool.execute({} as any, {
path: nestedPath,
content: "nested content",
});
expect(result).toContain("File written:");
const exists = await fs
.access(path.join(PROJECT_ROOT, nestedPath))
.then(() => true)
.catch(() => false);
expect(exists).toBe(true);
});
it("should return correct byte count", async () => {
const content = "Hello, World!";
const result = await tool.execute({} as any, {
path: "test-temp-write/bytecount.txt",
content: content,
});
const expectedBytes = Buffer.byteLength(content, "utf-8");
expect(result).toContain(`BYTES WRITTEN: ${expectedBytes}`);
});
it("should handle multiline content", async () => {
const content = "Line 1\nLine 2\nLine 3";
const result = await tool.execute({} as any, {
path: "test-temp-write/multiline.txt",
content: content,
});
expect(result).toContain("File written:");
const written = await fs.readFile(
path.join(PROJECT_ROOT, "test-temp-write/multiline.txt"),
"utf-8",
);
expect(written).toBe(content);
});
it("should handle empty content", async () => {
const result = await tool.execute({} as any, {
path: "test-temp-write/empty.txt",
content: "",
});
expect(result).toContain("BYTES WRITTEN: 0");
const written = await fs.readFile(
path.join(PROJECT_ROOT, "test-temp-write/empty.txt"),
"utf-8",
);
expect(written).toBe("");
});
it("should not return JSON format on success", async () => {
const result = await tool.execute({} as any, {
path: "test-temp-write/nojson.txt",
content: "test",
});
// Should not contain JSON structure
expect(result).not.toMatch(/^\s*\{/);
expect(result).not.toContain('"success":');
expect(result).not.toContain('"data":');
expect(result).not.toContain('"message":');
});
});