mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-30 01:06:11 +00:00
test: add unit tests for resolveSandboxedMediaSource
Add baseline test coverage for the previously untested resolveSandboxedMediaSource() function, covering sandbox-relative path resolution, rejection of paths outside the sandbox root, path traversal prevention, file:// URL handling, HTTP URL passthrough, and empty input edge cases.
This commit is contained in:
committed by
Peter Steinberger
parent
59563847e4
commit
4cf5c3e109
97
src/agents/sandbox-paths.test.ts
Normal file
97
src/agents/sandbox-paths.test.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { resolveSandboxedMediaSource } from "./sandbox-paths.js";
|
||||
|
||||
describe("resolveSandboxedMediaSource", () => {
|
||||
it("resolves sandbox-relative paths", async () => {
|
||||
const sandboxDir = await fs.mkdtemp(path.join(os.tmpdir(), "sandbox-media-"));
|
||||
try {
|
||||
const result = await resolveSandboxedMediaSource({
|
||||
media: "./data/file.txt",
|
||||
sandboxRoot: sandboxDir,
|
||||
});
|
||||
expect(result).toBe(path.join(sandboxDir, "data", "file.txt"));
|
||||
} finally {
|
||||
await fs.rm(sandboxDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("rejects paths outside sandbox root", async () => {
|
||||
const sandboxDir = await fs.mkdtemp(path.join(os.tmpdir(), "sandbox-media-"));
|
||||
try {
|
||||
await expect(
|
||||
resolveSandboxedMediaSource({ media: "/etc/passwd", sandboxRoot: sandboxDir }),
|
||||
).rejects.toThrow(/sandbox/i);
|
||||
} finally {
|
||||
await fs.rm(sandboxDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("rejects path traversal through tmpdir", async () => {
|
||||
const sandboxDir = await fs.mkdtemp(path.join(os.tmpdir(), "sandbox-media-"));
|
||||
try {
|
||||
await expect(
|
||||
resolveSandboxedMediaSource({
|
||||
media: path.join(os.tmpdir(), "..", "etc", "passwd"),
|
||||
sandboxRoot: sandboxDir,
|
||||
}),
|
||||
).rejects.toThrow(/sandbox/i);
|
||||
} finally {
|
||||
await fs.rm(sandboxDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("rejects file:// URLs outside sandbox", async () => {
|
||||
const sandboxDir = await fs.mkdtemp(path.join(os.tmpdir(), "sandbox-media-"));
|
||||
try {
|
||||
await expect(
|
||||
resolveSandboxedMediaSource({
|
||||
media: "file:///etc/passwd",
|
||||
sandboxRoot: sandboxDir,
|
||||
}),
|
||||
).rejects.toThrow(/sandbox/i);
|
||||
} finally {
|
||||
await fs.rm(sandboxDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("throws on invalid file:// URLs", async () => {
|
||||
const sandboxDir = await fs.mkdtemp(path.join(os.tmpdir(), "sandbox-media-"));
|
||||
try {
|
||||
await expect(
|
||||
resolveSandboxedMediaSource({
|
||||
media: "file://not a valid url\x00",
|
||||
sandboxRoot: sandboxDir,
|
||||
}),
|
||||
).rejects.toThrow(/Invalid file:\/\/ URL/);
|
||||
} finally {
|
||||
await fs.rm(sandboxDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("passes HTTP URLs through unchanged", async () => {
|
||||
const result = await resolveSandboxedMediaSource({
|
||||
media: "https://example.com/image.png",
|
||||
sandboxRoot: "/any/path",
|
||||
});
|
||||
expect(result).toBe("https://example.com/image.png");
|
||||
});
|
||||
|
||||
it("returns empty string for empty input", async () => {
|
||||
const result = await resolveSandboxedMediaSource({
|
||||
media: "",
|
||||
sandboxRoot: "/any/path",
|
||||
});
|
||||
expect(result).toBe("");
|
||||
});
|
||||
|
||||
it("returns empty string for whitespace-only input", async () => {
|
||||
const result = await resolveSandboxedMediaSource({
|
||||
media: " ",
|
||||
sandboxRoot: "/any/path",
|
||||
});
|
||||
expect(result).toBe("");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user