import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { sanitizeCommand, sanitizeErrorMessage, sanitizePath } from "./error-sanitization.js";
describe("sanitizeErrorMessage", () => {
const originalEnv = process.env.NODE_ENV;
afterEach(() => {
process.env.NODE_ENV = originalEnv;
});
describe("in production mode", () => {
beforeEach(() => {
process.env.NODE_ENV = "production";
});
it("should return generic message for sensitive errors", () => {
const result = sanitizeErrorMessage(
"Failed to read SSH private key at /home/user/.ssh/id_rsa",
"Configuration error"
);
expect(result).toBe("Configuration error");
expect(result).not.toContain("/home/user/.ssh/id_rsa");
});
it("should redact file paths from detailed messages", () => {
const result = sanitizeErrorMessage(
"File not found: /etc/secrets/api-key.txt",
"File operation failed"
);
expect(result).toBe("File operation failed");
expect(result).not.toContain("/etc/secrets");
});
it("should redact commands from error messages", () => {
const result = sanitizeErrorMessage(
"Command failed: grep secret /etc/passwd",
"Command execution failed"
);
expect(result).toBe("Command execution failed");
expect(result).not.toContain("grep secret");
});
});
describe("in development mode", () => {
beforeEach(() => {
process.env.NODE_ENV = "development";
});
it("should return detailed message in development", () => {
const detailed = "Failed to read SSH private key at /home/user/.ssh/id_rsa";
const result = sanitizeErrorMessage(detailed, "Configuration error");
expect(result).toBe(detailed);
expect(result).toContain("/home/user/.ssh/id_rsa");
});
it("should preserve file paths in development", () => {
const detailed = "File not found: /etc/secrets/api-key.txt";
const result = sanitizeErrorMessage(detailed, "File operation failed");
expect(result).toBe(detailed);
});
});
describe("when NODE_ENV is not set", () => {
beforeEach(() => {
process.env.NODE_ENV = undefined;
});
it("should default to production behavior (safe)", () => {
const result = sanitizeErrorMessage(
"Sensitive path: /home/user/.ssh/id_rsa",
"Operation failed"
);
expect(result).toBe("Operation failed");
expect(result).not.toContain("/home/user");
});
});
});
describe("sanitizePath", () => {
it("should redact file paths", () => {
expect(sanitizePath("/home/user/.ssh/id_rsa")).toBe("[REDACTED_PATH]");
expect(sanitizePath("/etc/passwd")).toBe("[REDACTED_PATH]");
expect(sanitizePath("./relative/path")).toBe("[REDACTED_PATH]");
});
it("should handle paths with spaces", () => {
expect(sanitizePath("/home/user/My Documents/secret.txt")).toBe("[REDACTED_PATH]");
});
it("should handle multiple paths in text", () => {
const text = "Failed to copy from /src/file.txt to /dst/file.txt";
const sanitized = text.replace(/\/[\w/.]+/g, sanitizePath);
expect(sanitized).toContain("[REDACTED_PATH]");
expect(sanitized).not.toContain("/src");
expect(sanitized).not.toContain("/dst");
});
});
describe("sanitizeCommand", () => {
it("should redact command strings", () => {
expect(sanitizeCommand("rm -rf /")).toBe("[REDACTED_COMMAND]");
expect(sanitizeCommand("grep secret file.txt")).toBe("[REDACTED_COMMAND]");
});
it("should handle commands with arguments", () => {
const cmd = "docker exec -it container bash -c 'cat /etc/passwd'";
expect(sanitizeCommand(cmd)).toBe("[REDACTED_COMMAND]");
});
});