test: reduce remaining clone seams

This commit is contained in:
Peter Steinberger
2026-03-26 19:59:48 +00:00
parent b20ae13c6b
commit 2fc017788c
9 changed files with 260 additions and 376 deletions

View File

@@ -126,6 +126,31 @@ function loadSingleCandidateRegistry(params: {
]);
}
function loadRegistryForMinHostVersionCase(params: {
rootDir: string;
minHostVersion: string;
env?: NodeJS.ProcessEnv;
}) {
return loadPluginManifestRegistry({
cache: false,
...(params.env ? { env: params.env } : {}),
candidates: [
createPluginCandidate({
idHint: "synology-chat",
rootDir: params.rootDir,
packageDir: params.rootDir,
origin: "global",
packageManifest: {
install: {
npmSpec: "@openclaw/synology-chat",
minHostVersion: params.minHostVersion,
},
},
}),
],
});
}
function hasUnsafeManifestDiagnostic(registry: ReturnType<typeof loadPluginManifestRegistry>) {
return registry.diagnostics.some((diag) => diag.message.includes("unsafe plugin manifest path"));
}
@@ -263,23 +288,10 @@ describe("loadPluginManifestRegistry", () => {
const dir = makeTempDir();
writeManifest(dir, { id: "synology-chat", configSchema: { type: "object" } });
const registry = loadPluginManifestRegistry({
cache: false,
const registry = loadRegistryForMinHostVersionCase({
rootDir: dir,
minHostVersion: ">=2026.3.22",
env: { OPENCLAW_VERSION: "2026.3.21" },
candidates: [
createPluginCandidate({
idHint: "synology-chat",
rootDir: dir,
packageDir: dir,
origin: "global",
packageManifest: {
install: {
npmSpec: "@openclaw/synology-chat",
minHostVersion: ">=2026.3.22",
},
},
}),
],
});
expect(registry.plugins).toEqual([]);
@@ -294,22 +306,9 @@ describe("loadPluginManifestRegistry", () => {
const dir = makeTempDir();
writeManifest(dir, { id: "synology-chat", configSchema: { type: "object" } });
const registry = loadPluginManifestRegistry({
cache: false,
candidates: [
createPluginCandidate({
idHint: "synology-chat",
rootDir: dir,
packageDir: dir,
origin: "global",
packageManifest: {
install: {
npmSpec: "@openclaw/synology-chat",
minHostVersion: "2026.3.22",
},
},
}),
],
const registry = loadRegistryForMinHostVersionCase({
rootDir: dir,
minHostVersion: "2026.3.22",
});
expect(registry.plugins).toEqual([]);
@@ -324,23 +323,10 @@ describe("loadPluginManifestRegistry", () => {
const dir = makeTempDir();
writeManifest(dir, { id: "synology-chat", configSchema: { type: "object" } });
const registry = loadPluginManifestRegistry({
cache: false,
const registry = loadRegistryForMinHostVersionCase({
rootDir: dir,
minHostVersion: ">=2026.3.22",
env: { OPENCLAW_VERSION: "unknown" },
candidates: [
createPluginCandidate({
idHint: "synology-chat",
rootDir: dir,
packageDir: dir,
origin: "global",
packageManifest: {
install: {
npmSpec: "@openclaw/synology-chat",
minHostVersion: ">=2026.3.22",
},
},
}),
],
});
expect(registry.plugins).toEqual([]);

View File

@@ -1,5 +1,4 @@
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { pathToFileURL } from "node:url";
import { afterAll, describe, expect, it, vi } from "vitest";
@@ -14,6 +13,7 @@ import {
resolvePluginSdkAliasFile,
shouldPreferNativeJiti,
} from "./sdk-alias.js";
import { makeTrackedTempDir, mkdirSafeDir } from "./test-helpers/fs-fixtures.js";
type CreateJiti = typeof import("jiti").createJiti;
@@ -24,30 +24,13 @@ async function getCreateJiti() {
return createJitiPromise;
}
function chmodSafeDir(dir: string) {
if (process.platform === "win32") {
return;
}
fs.chmodSync(dir, 0o755);
}
function mkdtempSafe(prefix: string) {
const dir = fs.mkdtempSync(prefix);
chmodSafeDir(dir);
return dir;
}
function mkdirSafe(dir: string) {
fs.mkdirSync(dir, { recursive: true });
chmodSafeDir(dir);
}
const fixtureRoot = mkdtempSafe(path.join(os.tmpdir(), "openclaw-sdk-alias-"));
const fixtureTempDirs: string[] = [];
const fixtureRoot = makeTrackedTempDir("openclaw-sdk-alias-root", fixtureTempDirs);
let tempDirIndex = 0;
function makeTempDir() {
const dir = path.join(fixtureRoot, `case-${tempDirIndex++}`);
mkdirSafe(dir);
mkdirSafeDir(dir);
return dir;
}
@@ -73,8 +56,8 @@ function createPluginSdkAliasFixture(params?: {
const root = makeTempDir();
const srcFile = path.join(root, "src", "plugin-sdk", params?.srcFile ?? "index.ts");
const distFile = path.join(root, "dist", "plugin-sdk", params?.distFile ?? "index.js");
mkdirSafe(path.dirname(srcFile));
mkdirSafe(path.dirname(distFile));
mkdirSafeDir(path.dirname(srcFile));
mkdirSafeDir(path.dirname(distFile));
const trustedRootIndicatorMode =
params?.trustedRootIndicatorMode ??
(params?.trustedRootIndicators === false ? "none" : "bin+marker");
@@ -111,8 +94,8 @@ function createExtensionApiAliasFixture(params?: { srcBody?: string; distBody?:
const root = makeTempDir();
const srcFile = path.join(root, "src", "extensionAPI.ts");
const distFile = path.join(root, "dist", "extensionAPI.js");
mkdirSafe(path.dirname(srcFile));
mkdirSafe(path.dirname(distFile));
mkdirSafeDir(path.dirname(srcFile));
mkdirSafeDir(path.dirname(distFile));
fs.writeFileSync(
path.join(root, "package.json"),
JSON.stringify({ name: "openclaw", type: "module" }, null, 2),
@@ -128,8 +111,8 @@ function createPluginRuntimeAliasFixture(params?: { srcBody?: string; distBody?:
const root = makeTempDir();
const srcFile = path.join(root, "src", "plugins", "runtime", "index.ts");
const distFile = path.join(root, "dist", "plugins", "runtime", "index.js");
mkdirSafe(path.dirname(srcFile));
mkdirSafe(path.dirname(distFile));
mkdirSafeDir(path.dirname(srcFile));
mkdirSafeDir(path.dirname(distFile));
fs.writeFileSync(
path.join(root, "package.json"),
JSON.stringify({ name: "openclaw", type: "module" }, null, 2),
@@ -148,6 +131,23 @@ function createPluginRuntimeAliasFixture(params?: { srcBody?: string; distBody?:
return { root, srcFile, distFile };
}
function createUserInstalledPluginSdkAliasFixture() {
const fixture = createPluginSdkAliasFixture({
srcFile: "channel-runtime.ts",
distFile: "channel-runtime.js",
packageExports: {
"./plugin-sdk/channel-runtime": { default: "./dist/plugin-sdk/channel-runtime.js" },
},
});
const sourceRootAlias = path.join(fixture.root, "src", "plugin-sdk", "root-alias.cjs");
fs.writeFileSync(sourceRootAlias, "module.exports = {};\n", "utf-8");
const externalPluginRoot = path.join(makeTempDir(), ".openclaw", "extensions", "demo");
const externalPluginEntry = path.join(externalPluginRoot, "index.ts");
mkdirSafeDir(externalPluginRoot);
fs.writeFileSync(externalPluginEntry, 'export const plugin = "demo";\n', "utf-8");
return { externalPluginEntry, externalPluginRoot, fixture, sourceRootAlias };
}
function resolvePluginSdkAlias(params: {
srcFile: string;
distFile: string;
@@ -470,19 +470,8 @@ describe("plugin sdk alias helpers", () => {
});
it("resolves plugin-sdk aliases for user-installed plugins via the running openclaw argv hint", () => {
const fixture = createPluginSdkAliasFixture({
srcFile: "channel-runtime.ts",
distFile: "channel-runtime.js",
packageExports: {
"./plugin-sdk/channel-runtime": { default: "./dist/plugin-sdk/channel-runtime.js" },
},
});
const sourceRootAlias = path.join(fixture.root, "src", "plugin-sdk", "root-alias.cjs");
fs.writeFileSync(sourceRootAlias, "module.exports = {};\n", "utf-8");
const externalPluginRoot = path.join(makeTempDir(), ".openclaw", "extensions", "demo");
const externalPluginEntry = path.join(externalPluginRoot, "index.ts");
mkdirSafe(externalPluginRoot);
fs.writeFileSync(externalPluginEntry, 'export const plugin = "demo";\n', "utf-8");
const { externalPluginEntry, externalPluginRoot, fixture, sourceRootAlias } =
createUserInstalledPluginSdkAliasFixture();
const aliases = withCwd(externalPluginRoot, () =>
withEnv({ NODE_ENV: undefined }, () =>
@@ -499,19 +488,8 @@ describe("plugin sdk alias helpers", () => {
});
it("resolves plugin-sdk aliases for user-installed plugins via moduleUrl hint", () => {
const fixture = createPluginSdkAliasFixture({
srcFile: "channel-runtime.ts",
distFile: "channel-runtime.js",
packageExports: {
"./plugin-sdk/channel-runtime": { default: "./dist/plugin-sdk/channel-runtime.js" },
},
});
const sourceRootAlias = path.join(fixture.root, "src", "plugin-sdk", "root-alias.cjs");
fs.writeFileSync(sourceRootAlias, "module.exports = {};\n", "utf-8");
const externalPluginRoot = path.join(makeTempDir(), ".openclaw", "extensions", "demo");
const externalPluginEntry = path.join(externalPluginRoot, "index.ts");
mkdirSafe(externalPluginRoot);
fs.writeFileSync(externalPluginEntry, 'export const plugin = "demo";\n', "utf-8");
const { externalPluginEntry, externalPluginRoot, fixture, sourceRootAlias } =
createUserInstalledPluginSdkAliasFixture();
// Simulate loader.ts passing its own import.meta.url as the moduleUrl hint.
// This covers installations where argv1 does not resolve to the openclaw root
@@ -585,8 +563,8 @@ describe("plugin sdk alias helpers", () => {
const copiedExtensionRoot = path.join(makeTempDir(), "extensions", "discord");
const copiedSourceDir = path.join(copiedExtensionRoot, "src");
const copiedPluginSdkDir = path.join(copiedExtensionRoot, "plugin-sdk");
mkdirSafe(copiedSourceDir);
mkdirSafe(copiedPluginSdkDir);
mkdirSafeDir(copiedSourceDir);
mkdirSafeDir(copiedPluginSdkDir);
const jitiBaseFile = path.join(copiedSourceDir, "__jiti-base__.mjs");
fs.writeFileSync(jitiBaseFile, "export {};\n", "utf-8");
fs.writeFileSync(