mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-14 10:41:23 +00:00
test(plugins): share suite temp root helper in install path tests
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
mockNpmPackMetadataResult,
|
||||
} from "../test-utils/npm-spec-install-test-helpers.js";
|
||||
import { installPluginFromNpmSpec, PLUGIN_INSTALL_ERROR_CODE } from "./install.js";
|
||||
import { createSuiteTempRootTracker } from "./test-helpers/fs-fixtures.js";
|
||||
|
||||
const runCommandWithTimeoutMock = vi.fn();
|
||||
|
||||
@@ -15,27 +16,9 @@ vi.mock("../process/exec.js", () => ({
|
||||
runCommandWithTimeout: (...args: unknown[]) => runCommandWithTimeoutMock(...args),
|
||||
}));
|
||||
|
||||
let suiteTempRoot = "";
|
||||
let tempDirCounter = 0;
|
||||
const dynamicArchiveTemplatePathCache = new Map<string, string>();
|
||||
const pluginFixturesDir = path.resolve(process.cwd(), "test", "fixtures", "plugins-install");
|
||||
|
||||
function ensureSuiteTempRoot() {
|
||||
if (suiteTempRoot) {
|
||||
return suiteTempRoot;
|
||||
}
|
||||
const bundleTempRoot = path.join(process.cwd(), ".tmp");
|
||||
fs.mkdirSync(bundleTempRoot, { recursive: true });
|
||||
suiteTempRoot = fs.mkdtempSync(path.join(bundleTempRoot, "openclaw-plugin-install-npm-spec-"));
|
||||
return suiteTempRoot;
|
||||
}
|
||||
|
||||
function makeTempDir() {
|
||||
const dir = path.join(ensureSuiteTempRoot(), `case-${String(tempDirCounter)}`);
|
||||
tempDirCounter += 1;
|
||||
fs.mkdirSync(dir);
|
||||
return dir;
|
||||
}
|
||||
const suiteTempRootTracker = createSuiteTempRootTracker("openclaw-plugin-install-npm-spec");
|
||||
|
||||
function readVoiceCallArchiveBuffer(version: string): Buffer {
|
||||
return fs.readFileSync(path.join(pluginFixturesDir, `voice-call-${version}.tgz`));
|
||||
@@ -92,7 +75,7 @@ async function ensureDynamicArchiveTemplate(params: {
|
||||
if (cachedPath) {
|
||||
return cachedPath;
|
||||
}
|
||||
const templateDir = makeTempDir();
|
||||
const templateDir = suiteTempRootTracker.makeTempDir();
|
||||
const pkgDir = params.flatRoot ? templateDir : path.join(templateDir, "package");
|
||||
fs.mkdirSync(pkgDir, { recursive: true });
|
||||
if (params.withDistIndex) {
|
||||
@@ -106,7 +89,7 @@ async function ensureDynamicArchiveTemplate(params: {
|
||||
fs.writeFileSync(path.join(pkgDir, "package.json"), JSON.stringify(params.packageJson), "utf-8");
|
||||
const archivePath = await packToArchive({
|
||||
pkgDir,
|
||||
outDir: ensureSuiteTempRoot(),
|
||||
outDir: suiteTempRootTracker.ensureSuiteTempRoot(),
|
||||
outName: params.outName,
|
||||
flatRoot: params.flatRoot,
|
||||
});
|
||||
@@ -115,16 +98,8 @@ async function ensureDynamicArchiveTemplate(params: {
|
||||
}
|
||||
|
||||
afterAll(() => {
|
||||
if (!suiteTempRoot) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
fs.rmSync(suiteTempRoot, { recursive: true, force: true });
|
||||
} finally {
|
||||
suiteTempRoot = "";
|
||||
tempDirCounter = 0;
|
||||
dynamicArchiveTemplatePathCache.clear();
|
||||
}
|
||||
suiteTempRootTracker.cleanup();
|
||||
dynamicArchiveTemplatePathCache.clear();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -134,7 +109,7 @@ beforeEach(() => {
|
||||
|
||||
describe("installPluginFromNpmSpec", () => {
|
||||
it("uses --ignore-scripts for npm pack and cleans up temp dir", async () => {
|
||||
const stateDir = makeTempDir();
|
||||
const stateDir = suiteTempRootTracker.makeTempDir();
|
||||
const extensionsDir = path.join(stateDir, "extensions");
|
||||
fs.mkdirSync(extensionsDir, { recursive: true });
|
||||
|
||||
@@ -190,7 +165,7 @@ describe("installPluginFromNpmSpec", () => {
|
||||
});
|
||||
|
||||
it("allows npm-spec installs with dangerous code patterns when forced unsafe install is set", async () => {
|
||||
const stateDir = makeTempDir();
|
||||
const stateDir = suiteTempRootTracker.makeTempDir();
|
||||
const extensionsDir = path.join(stateDir, "extensions");
|
||||
fs.mkdirSync(extensionsDir, { recursive: true });
|
||||
|
||||
@@ -364,7 +339,7 @@ describe("installPluginFromNpmSpec", () => {
|
||||
throw new Error(`unexpected command: ${argv.join(" ")}`);
|
||||
});
|
||||
|
||||
const stateDir = makeTempDir();
|
||||
const stateDir = suiteTempRootTracker.makeTempDir();
|
||||
const extensionsDir = path.join(stateDir, "extensions");
|
||||
fs.mkdirSync(extensionsDir, { recursive: true });
|
||||
const result = await installPluginFromNpmSpec({
|
||||
|
||||
@@ -11,30 +11,13 @@ import {
|
||||
installPluginFromPath,
|
||||
PLUGIN_INSTALL_ERROR_CODE,
|
||||
} from "./install.js";
|
||||
import { createSuiteTempRootTracker } from "./test-helpers/fs-fixtures.js";
|
||||
|
||||
vi.mock("../process/exec.js", () => ({
|
||||
runCommandWithTimeout: vi.fn(),
|
||||
}));
|
||||
|
||||
let suiteTempRoot = "";
|
||||
let tempDirCounter = 0;
|
||||
|
||||
function ensureSuiteTempRoot() {
|
||||
if (suiteTempRoot) {
|
||||
return suiteTempRoot;
|
||||
}
|
||||
const bundleTempRoot = path.join(process.cwd(), ".tmp");
|
||||
fs.mkdirSync(bundleTempRoot, { recursive: true });
|
||||
suiteTempRoot = fs.mkdtempSync(path.join(bundleTempRoot, "openclaw-plugin-install-path-"));
|
||||
return suiteTempRoot;
|
||||
}
|
||||
|
||||
function makeTempDir() {
|
||||
const dir = path.join(ensureSuiteTempRoot(), `case-${String(tempDirCounter)}`);
|
||||
tempDirCounter += 1;
|
||||
fs.mkdirSync(dir);
|
||||
return dir;
|
||||
}
|
||||
const suiteTempRootTracker = createSuiteTempRootTracker("openclaw-plugin-install-path");
|
||||
|
||||
async function packToArchive(params: {
|
||||
pkgDir: string;
|
||||
@@ -60,7 +43,7 @@ function setupBundleInstallFixture(params: {
|
||||
bundleFormat: "codex" | "claude" | "cursor";
|
||||
name: string;
|
||||
}) {
|
||||
const caseDir = makeTempDir();
|
||||
const caseDir = suiteTempRootTracker.makeTempDir();
|
||||
const stateDir = path.join(caseDir, "state");
|
||||
const pluginDir = path.join(caseDir, "plugin-src");
|
||||
fs.mkdirSync(stateDir, { recursive: true });
|
||||
@@ -100,7 +83,7 @@ function setupBundleInstallFixture(params: {
|
||||
}
|
||||
|
||||
function setupDualFormatInstallFixture(params: { bundleFormat: "codex" | "claude" }) {
|
||||
const caseDir = makeTempDir();
|
||||
const caseDir = suiteTempRootTracker.makeTempDir();
|
||||
const stateDir = path.join(caseDir, "state");
|
||||
const pluginDir = path.join(caseDir, "plugin-src");
|
||||
fs.mkdirSync(path.join(pluginDir, "dist"), { recursive: true });
|
||||
@@ -161,15 +144,7 @@ async function installFromFileWithWarnings(params: {
|
||||
}
|
||||
|
||||
afterAll(() => {
|
||||
if (!suiteTempRoot) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
fs.rmSync(suiteTempRoot, { recursive: true, force: true });
|
||||
} finally {
|
||||
suiteTempRoot = "";
|
||||
tempDirCounter = 0;
|
||||
}
|
||||
suiteTempRootTracker.cleanup();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -193,7 +168,7 @@ describe("installPluginFromPath", () => {
|
||||
});
|
||||
initializeGlobalHookRunner(createMockPluginRegistry([{ hookName: "before_install", handler }]));
|
||||
|
||||
const baseDir = makeTempDir();
|
||||
const baseDir = suiteTempRootTracker.makeTempDir();
|
||||
const extensionsDir = path.join(baseDir, "extensions");
|
||||
fs.mkdirSync(extensionsDir, { recursive: true });
|
||||
|
||||
@@ -235,7 +210,7 @@ describe("installPluginFromPath", () => {
|
||||
});
|
||||
|
||||
it("blocks plain file installs when the scanner finds dangerous code patterns", async () => {
|
||||
const baseDir = makeTempDir();
|
||||
const baseDir = suiteTempRootTracker.makeTempDir();
|
||||
const extensionsDir = path.join(baseDir, "extensions");
|
||||
fs.mkdirSync(extensionsDir, { recursive: true });
|
||||
|
||||
@@ -256,7 +231,7 @@ describe("installPluginFromPath", () => {
|
||||
});
|
||||
|
||||
it("allows plain file installs with dangerous code patterns when forced unsafe install is set", async () => {
|
||||
const baseDir = makeTempDir();
|
||||
const baseDir = suiteTempRootTracker.makeTempDir();
|
||||
const extensionsDir = path.join(baseDir, "extensions");
|
||||
fs.mkdirSync(extensionsDir, { recursive: true });
|
||||
|
||||
@@ -280,7 +255,7 @@ describe("installPluginFromPath", () => {
|
||||
});
|
||||
|
||||
it("blocks hardlink alias overwrites when installing a plain file plugin", async () => {
|
||||
const baseDir = makeTempDir();
|
||||
const baseDir = suiteTempRootTracker.makeTempDir();
|
||||
const extensionsDir = path.join(baseDir, "extensions");
|
||||
const outsideDir = path.join(baseDir, "outside");
|
||||
fs.mkdirSync(extensionsDir, { recursive: true });
|
||||
@@ -313,7 +288,7 @@ describe("installPluginFromPath", () => {
|
||||
bundleFormat: "claude",
|
||||
name: "Claude Sample",
|
||||
});
|
||||
const archivePath = path.join(makeTempDir(), "claude-bundle.tgz");
|
||||
const archivePath = path.join(suiteTempRootTracker.makeTempDir(), "claude-bundle.tgz");
|
||||
|
||||
await packToArchive({
|
||||
pkgDir: pluginDir,
|
||||
@@ -337,7 +312,7 @@ describe("installPluginFromPath", () => {
|
||||
const { pluginDir, extensionsDir } = setupDualFormatInstallFixture({
|
||||
bundleFormat: "claude",
|
||||
});
|
||||
const archivePath = path.join(makeTempDir(), "dual-format.tgz");
|
||||
const archivePath = path.join(suiteTempRootTracker.makeTempDir(), "dual-format.tgz");
|
||||
|
||||
await packToArchive({
|
||||
pkgDir: pluginDir,
|
||||
|
||||
@@ -50,3 +50,43 @@ export async function cleanupTrackedTempDirsAsync(trackedDirs: string[]) {
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
export function createSuiteTempRootTracker(prefix: string) {
|
||||
let suiteTempRoot = "";
|
||||
let tempDirCounter = 0;
|
||||
|
||||
function ensureSuiteTempRoot() {
|
||||
if (suiteTempRoot) {
|
||||
return suiteTempRoot;
|
||||
}
|
||||
const bundleTempRoot = path.join(process.cwd(), ".tmp");
|
||||
fs.mkdirSync(bundleTempRoot, { recursive: true });
|
||||
suiteTempRoot = fs.mkdtempSync(path.join(bundleTempRoot, String(prefix) + "-"));
|
||||
return suiteTempRoot;
|
||||
}
|
||||
|
||||
function makeTempDir() {
|
||||
const dir = path.join(ensureSuiteTempRoot(), `case-${String(tempDirCounter)}`);
|
||||
tempDirCounter += 1;
|
||||
fs.mkdirSync(dir);
|
||||
return dir;
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
if (!suiteTempRoot) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
fs.rmSync(suiteTempRoot, { recursive: true, force: true });
|
||||
} finally {
|
||||
suiteTempRoot = "";
|
||||
tempDirCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
cleanup,
|
||||
ensureSuiteTempRoot,
|
||||
makeTempDir,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user