mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-11 17:21:13 +00:00
130 lines
4.1 KiB
TypeScript
130 lines
4.1 KiB
TypeScript
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { withTempDir } from "../test-helpers/temp-dir.js";
|
|
|
|
const fileExistsMock = vi.hoisted(() => vi.fn());
|
|
const resolveSafeInstallDirMock = vi.hoisted(() => vi.fn());
|
|
const assertCanonicalPathWithinBaseMock = vi.hoisted(() => vi.fn());
|
|
|
|
vi.mock("./archive.js", () => ({
|
|
fileExists: (...args: unknown[]) => fileExistsMock(...args),
|
|
}));
|
|
|
|
vi.mock("./install-safe-path.js", () => ({
|
|
resolveSafeInstallDir: (...args: unknown[]) => resolveSafeInstallDirMock(...args),
|
|
assertCanonicalPathWithinBase: (...args: unknown[]) => assertCanonicalPathWithinBaseMock(...args),
|
|
}));
|
|
|
|
import { ensureInstallTargetAvailable, resolveCanonicalInstallTarget } from "./install-target.js";
|
|
|
|
beforeEach(() => {
|
|
fileExistsMock.mockReset();
|
|
resolveSafeInstallDirMock.mockReset();
|
|
assertCanonicalPathWithinBaseMock.mockReset();
|
|
});
|
|
|
|
describe("resolveCanonicalInstallTarget", () => {
|
|
it("creates the base dir and returns early for invalid install ids", async () => {
|
|
await withTempDir({ prefix: "openclaw-install-target-" }, async (root) => {
|
|
const baseDir = path.join(root, "plugins");
|
|
resolveSafeInstallDirMock.mockReturnValueOnce({
|
|
ok: false,
|
|
error: "bad id",
|
|
});
|
|
|
|
await expect(
|
|
resolveCanonicalInstallTarget({
|
|
baseDir,
|
|
id: "../oops",
|
|
invalidNameMessage: "bad id",
|
|
boundaryLabel: "plugin dir",
|
|
}),
|
|
).resolves.toEqual({ ok: false, error: "bad id" });
|
|
|
|
await expect(fs.stat(baseDir)).resolves.toMatchObject({ isDirectory: expect.any(Function) });
|
|
expect(assertCanonicalPathWithinBaseMock).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
it("returns canonical boundary errors for Error and non-Error throws", async () => {
|
|
await withTempDir({ prefix: "openclaw-install-target-" }, async (baseDir) => {
|
|
const targetDir = path.join(baseDir, "demo");
|
|
resolveSafeInstallDirMock.mockReturnValue({
|
|
ok: true,
|
|
path: targetDir,
|
|
});
|
|
assertCanonicalPathWithinBaseMock.mockRejectedValueOnce(new Error("escaped"));
|
|
assertCanonicalPathWithinBaseMock.mockRejectedValueOnce("boom");
|
|
|
|
await expect(
|
|
resolveCanonicalInstallTarget({
|
|
baseDir,
|
|
id: "demo",
|
|
invalidNameMessage: "bad id",
|
|
boundaryLabel: "plugin dir",
|
|
}),
|
|
).resolves.toEqual({ ok: false, error: "escaped" });
|
|
|
|
await expect(
|
|
resolveCanonicalInstallTarget({
|
|
baseDir,
|
|
id: "demo",
|
|
invalidNameMessage: "bad id",
|
|
boundaryLabel: "plugin dir",
|
|
}),
|
|
).resolves.toEqual({ ok: false, error: "boom" });
|
|
});
|
|
});
|
|
|
|
it("returns the resolved target path on success", async () => {
|
|
await withTempDir({ prefix: "openclaw-install-target-" }, async (baseDir) => {
|
|
const targetDir = path.join(baseDir, "demo");
|
|
resolveSafeInstallDirMock.mockReturnValueOnce({
|
|
ok: true,
|
|
path: targetDir,
|
|
});
|
|
|
|
await expect(
|
|
resolveCanonicalInstallTarget({
|
|
baseDir,
|
|
id: "demo",
|
|
invalidNameMessage: "bad id",
|
|
boundaryLabel: "plugin dir",
|
|
}),
|
|
).resolves.toEqual({ ok: true, targetDir });
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("ensureInstallTargetAvailable", () => {
|
|
it("blocks only install mode when the target already exists", async () => {
|
|
fileExistsMock.mockResolvedValueOnce(true);
|
|
fileExistsMock.mockResolvedValueOnce(false);
|
|
|
|
await expect(
|
|
ensureInstallTargetAvailable({
|
|
mode: "install",
|
|
targetDir: "/tmp/demo",
|
|
alreadyExistsError: "already there",
|
|
}),
|
|
).resolves.toEqual({ ok: false, error: "already there" });
|
|
|
|
await expect(
|
|
ensureInstallTargetAvailable({
|
|
mode: "update",
|
|
targetDir: "/tmp/demo",
|
|
alreadyExistsError: "already there",
|
|
}),
|
|
).resolves.toEqual({ ok: true });
|
|
|
|
await expect(
|
|
ensureInstallTargetAvailable({
|
|
mode: "install",
|
|
targetDir: "/tmp/demo",
|
|
alreadyExistsError: "already there",
|
|
}),
|
|
).resolves.toEqual({ ok: true });
|
|
});
|
|
});
|