mirror of
https://github.com/luckyyzh/pi-agent-integrated.git
synced 2026-10-03 02:59:35 +00:00
71 lines
2.4 KiB
JavaScript
71 lines
2.4 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import test from "node:test";
|
|
|
|
async function loadSubject() {
|
|
return import("./file-upload.ts");
|
|
}
|
|
|
|
test("validates upload names without accepting paths or duplicates", async () => {
|
|
const { validateUploadFileNames } = await loadSubject();
|
|
|
|
assert.equal(validateUploadFileNames(["one.txt", "two file.md"]), null);
|
|
assert.match(validateUploadFileNames(["../secret.txt"]), /must not contain a path/);
|
|
assert.match(validateUploadFileNames(["folder\\secret.txt"]), /must not contain a path/);
|
|
assert.match(validateUploadFileNames(["same.txt", "same.txt"]), /Duplicate/);
|
|
assert.match(validateUploadFileNames([]), /No files/);
|
|
});
|
|
|
|
test("finds conflicts and prevents replacing directories", async (t) => {
|
|
const { inspectUploadTargets } = await loadSubject();
|
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), "pi-web-upload-"));
|
|
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
|
|
|
fs.writeFileSync(path.join(root, "file.txt"), "old");
|
|
fs.mkdirSync(path.join(root, "directory"));
|
|
|
|
assert.deepEqual(
|
|
inspectUploadTargets(root, ["new.txt", "file.txt", "directory"]),
|
|
{
|
|
conflicts: ["file.txt", "directory"],
|
|
nonReplaceable: ["directory"],
|
|
},
|
|
);
|
|
});
|
|
|
|
test("prevents replacing symbolic links", async (t) => {
|
|
const { inspectUploadTargets } = await loadSubject();
|
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), "pi-web-upload-link-"));
|
|
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
|
|
|
fs.writeFileSync(path.join(root, "file.txt"), "old");
|
|
try {
|
|
fs.symlinkSync("file.txt", path.join(root, "link.txt"));
|
|
} catch (error) {
|
|
if (error?.code === "EPERM") {
|
|
t.skip("Creating symbolic links requires additional privileges on this platform");
|
|
return;
|
|
}
|
|
throw error;
|
|
}
|
|
|
|
assert.deepEqual(
|
|
inspectUploadTargets(root, ["link.txt"]),
|
|
{
|
|
conflicts: ["link.txt"],
|
|
nonReplaceable: ["link.txt"],
|
|
},
|
|
);
|
|
});
|
|
|
|
test("parses only supported conflict strategies", async () => {
|
|
const { parseUploadConflictStrategy } = await loadSubject();
|
|
|
|
assert.equal(parseUploadConflictStrategy(null), "error");
|
|
assert.equal(parseUploadConflictStrategy("overwrite"), "overwrite");
|
|
assert.equal(parseUploadConflictStrategy("skip"), "skip");
|
|
assert.equal(parseUploadConflictStrategy("rename"), null);
|
|
});
|