import { describe, expect, it } from "vitest"; import { importableRoutines, relativeImportedFiles, safeImportPath } from "./bot-import.js"; describe("safeImportPath", () => { it("normalizes separators and dot segments", () => { expect(safeImportPath("notes\\./result.txt")).toBe("notes/result.txt"); expect(safeImportPath("MEMORY.md")).toBe("MEMORY.md"); }); it("rejects paths that could leave the bot home", () => { expect(safeImportPath("../secrets")).toBeNull(); expect(safeImportPath("notes/../../x")).toBeNull(); expect(safeImportPath("/etc/passwd")).toBeNull(); expect(safeImportPath("C:\\Windows")).toBeNull(); expect(safeImportPath("./")).toBeNull(); }); }); describe("relativeImportedFiles", () => { it("drops the old Team Computer workspace prefix", () => { expect( relativeImportedFiles([ { path: "bots/old-id/notes/result.txt", content: "a" }, { path: "bots/old-id/README.md", content: "b" }, ]), ).toEqual([ { path: "notes/result.txt", content: "a" }, { path: "README.md", content: "b" }, ]); }); it("keeps Private Computer paths as they are", () => { const files = [ { path: "notes/result.txt", content: "a" }, { path: "bots/other/file.txt", content: "b" }, ]; expect(relativeImportedFiles(files)).toEqual(files); }); it("keeps paths when files span several workspaces", () => { const files = [ { path: "bots/a/x.txt", content: "a" }, { path: "bots/b/y.txt", content: "b" }, ]; expect(relativeImportedFiles(files)).toEqual(files); }); it("refuses the whole set when one path is unsafe", () => { expect( relativeImportedFiles([ { path: "ok.txt", content: "a" }, { path: "../escape.txt", content: "b" }, ]), ).toBeNull(); }); it("accepts an export without files", () => { expect(relativeImportedFiles([])).toEqual([]); }); }); describe("importableRoutines", () => { it("leaves out one-shot schedules", () => { const routines = [ { name: "daily", crons: ["0 9 * * *"] }, { name: "once", crons: ["@once"] }, { name: "webhook", crons: [] }, ]; expect(importableRoutines(routines).map((routine) => routine.name)).toEqual([ "daily", "webhook", ]); }); });