mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-02 15:17:15 +00:00
test: cache plugin install archive fixtures
This commit is contained in:
@@ -4,7 +4,7 @@ import os from "node:os";
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import JSZip from "jszip";
|
import JSZip from "jszip";
|
||||||
import * as tar from "tar";
|
import * as tar from "tar";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import * as skillScanner from "../security/skill-scanner.js";
|
import * as skillScanner from "../security/skill-scanner.js";
|
||||||
import {
|
import {
|
||||||
expectSingleNpmInstallIgnoreScriptsCall,
|
expectSingleNpmInstallIgnoreScriptsCall,
|
||||||
@@ -93,14 +93,55 @@ async function createVoiceCallArchive(params: {
|
|||||||
return { pkgDir, archivePath };
|
return { pkgDir, archivePath };
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setupVoiceCallArchiveInstall(params: { outName: string; version: string }) {
|
async function createVoiceCallArchiveBuffer(version: string): Promise<Buffer> {
|
||||||
const stateDir = makeTempDir();
|
|
||||||
const workDir = makeTempDir();
|
const workDir = makeTempDir();
|
||||||
const { archivePath } = await createVoiceCallArchive({
|
const { archivePath } = await createVoiceCallArchive({
|
||||||
workDir,
|
workDir,
|
||||||
outName: params.outName,
|
outName: `plugin-${version}.tgz`,
|
||||||
version: params.version,
|
version,
|
||||||
});
|
});
|
||||||
|
return fs.readFileSync(archivePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeArchiveBuffer(params: { outName: string; buffer: Buffer }): string {
|
||||||
|
const workDir = makeTempDir();
|
||||||
|
const archivePath = path.join(workDir, params.outName);
|
||||||
|
fs.writeFileSync(archivePath, params.buffer);
|
||||||
|
return archivePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createZipperArchiveBuffer(): Promise<Buffer> {
|
||||||
|
const zip = new JSZip();
|
||||||
|
zip.file(
|
||||||
|
"package/package.json",
|
||||||
|
JSON.stringify({
|
||||||
|
name: "@openclaw/zipper",
|
||||||
|
version: "0.0.1",
|
||||||
|
openclaw: { extensions: ["./dist/index.js"] },
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
zip.file("package/dist/index.js", "export {};");
|
||||||
|
return zip.generateAsync({ type: "nodebuffer" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const VOICE_CALL_ARCHIVE_V1_BUFFER_PROMISE = createVoiceCallArchiveBuffer("0.0.1");
|
||||||
|
const VOICE_CALL_ARCHIVE_V2_BUFFER_PROMISE = createVoiceCallArchiveBuffer("0.0.2");
|
||||||
|
const ZIPPER_ARCHIVE_BUFFER_PROMISE = createZipperArchiveBuffer();
|
||||||
|
|
||||||
|
async function getVoiceCallArchiveBuffer(version: string): Promise<Buffer> {
|
||||||
|
if (version === "0.0.1") {
|
||||||
|
return VOICE_CALL_ARCHIVE_V1_BUFFER_PROMISE;
|
||||||
|
}
|
||||||
|
if (version === "0.0.2") {
|
||||||
|
return VOICE_CALL_ARCHIVE_V2_BUFFER_PROMISE;
|
||||||
|
}
|
||||||
|
return createVoiceCallArchiveBuffer(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setupVoiceCallArchiveInstall(params: { outName: string; version: string }) {
|
||||||
|
const stateDir = makeTempDir();
|
||||||
|
const archiveBuffer = await getVoiceCallArchiveBuffer(params.version);
|
||||||
|
const archivePath = writeArchiveBuffer({ outName: params.outName, buffer: archiveBuffer });
|
||||||
return {
|
return {
|
||||||
stateDir,
|
stateDir,
|
||||||
archivePath,
|
archivePath,
|
||||||
@@ -174,7 +215,7 @@ async function expectArchiveInstallReservedSegmentRejection(params: {
|
|||||||
expect(result.error).toContain("reserved path segment");
|
expect(result.error).toContain("reserved path segment");
|
||||||
}
|
}
|
||||||
|
|
||||||
afterEach(() => {
|
afterAll(() => {
|
||||||
for (const dir of tempDirs.splice(0)) {
|
for (const dir of tempDirs.splice(0)) {
|
||||||
try {
|
try {
|
||||||
fs.rmSync(dir, { recursive: true, force: true });
|
fs.rmSync(dir, { recursive: true, force: true });
|
||||||
@@ -238,21 +279,10 @@ describe("installPluginFromArchive", () => {
|
|||||||
|
|
||||||
it("installs from a zip archive", async () => {
|
it("installs from a zip archive", async () => {
|
||||||
const stateDir = makeTempDir();
|
const stateDir = makeTempDir();
|
||||||
const workDir = makeTempDir();
|
const archivePath = writeArchiveBuffer({
|
||||||
const archivePath = path.join(workDir, "plugin.zip");
|
outName: "plugin.zip",
|
||||||
|
buffer: await ZIPPER_ARCHIVE_BUFFER_PROMISE,
|
||||||
const zip = new JSZip();
|
});
|
||||||
zip.file(
|
|
||||||
"package/package.json",
|
|
||||||
JSON.stringify({
|
|
||||||
name: "@openclaw/zipper",
|
|
||||||
version: "0.0.1",
|
|
||||||
openclaw: { extensions: ["./dist/index.js"] },
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
zip.file("package/dist/index.js", "export {};");
|
|
||||||
const buffer = await zip.generateAsync({ type: "nodebuffer" });
|
|
||||||
fs.writeFileSync(archivePath, buffer);
|
|
||||||
|
|
||||||
const extensionsDir = path.join(stateDir, "extensions");
|
const extensionsDir = path.join(stateDir, "extensions");
|
||||||
const result = await installPluginFromArchive({
|
const result = await installPluginFromArchive({
|
||||||
@@ -270,16 +300,13 @@ describe("installPluginFromArchive", () => {
|
|||||||
|
|
||||||
it("allows updates when mode is update", async () => {
|
it("allows updates when mode is update", async () => {
|
||||||
const stateDir = makeTempDir();
|
const stateDir = makeTempDir();
|
||||||
const workDir = makeTempDir();
|
const archiveV1 = writeArchiveBuffer({
|
||||||
const { archivePath: archiveV1 } = await createVoiceCallArchive({
|
|
||||||
workDir,
|
|
||||||
outName: "plugin-v1.tgz",
|
outName: "plugin-v1.tgz",
|
||||||
version: "0.0.1",
|
buffer: await VOICE_CALL_ARCHIVE_V1_BUFFER_PROMISE,
|
||||||
});
|
});
|
||||||
const { archivePath: archiveV2 } = await createVoiceCallArchive({
|
const archiveV2 = writeArchiveBuffer({
|
||||||
workDir,
|
|
||||||
outName: "plugin-v2.tgz",
|
outName: "plugin-v2.tgz",
|
||||||
version: "0.0.2",
|
buffer: await VOICE_CALL_ARCHIVE_V2_BUFFER_PROMISE,
|
||||||
});
|
});
|
||||||
|
|
||||||
const extensionsDir = path.join(stateDir, "extensions");
|
const extensionsDir = path.join(stateDir, "extensions");
|
||||||
@@ -463,32 +490,20 @@ describe("installPluginFromDir", () => {
|
|||||||
|
|
||||||
describe("installPluginFromNpmSpec", () => {
|
describe("installPluginFromNpmSpec", () => {
|
||||||
it("uses --ignore-scripts for npm pack and cleans up temp dir", async () => {
|
it("uses --ignore-scripts for npm pack and cleans up temp dir", async () => {
|
||||||
const workDir = makeTempDir();
|
|
||||||
const stateDir = makeTempDir();
|
const stateDir = makeTempDir();
|
||||||
const pkgDir = path.join(workDir, "package");
|
|
||||||
fs.mkdirSync(path.join(pkgDir, "dist"), { recursive: true });
|
|
||||||
fs.writeFileSync(
|
|
||||||
path.join(pkgDir, "package.json"),
|
|
||||||
JSON.stringify({
|
|
||||||
name: "@openclaw/voice-call",
|
|
||||||
version: "0.0.1",
|
|
||||||
openclaw: { extensions: ["./dist/index.js"] },
|
|
||||||
}),
|
|
||||||
"utf-8",
|
|
||||||
);
|
|
||||||
fs.writeFileSync(path.join(pkgDir, "dist", "index.js"), "export {};", "utf-8");
|
|
||||||
|
|
||||||
const extensionsDir = path.join(stateDir, "extensions");
|
const extensionsDir = path.join(stateDir, "extensions");
|
||||||
fs.mkdirSync(extensionsDir, { recursive: true });
|
fs.mkdirSync(extensionsDir, { recursive: true });
|
||||||
|
|
||||||
const run = vi.mocked(runCommandWithTimeout);
|
const run = vi.mocked(runCommandWithTimeout);
|
||||||
|
const voiceCallArchiveBuffer = await VOICE_CALL_ARCHIVE_V1_BUFFER_PROMISE;
|
||||||
|
|
||||||
let packTmpDir = "";
|
let packTmpDir = "";
|
||||||
const packedName = "voice-call-0.0.1.tgz";
|
const packedName = "voice-call-0.0.1.tgz";
|
||||||
run.mockImplementation(async (argv, opts) => {
|
run.mockImplementation(async (argv, opts) => {
|
||||||
if (argv[0] === "npm" && argv[1] === "pack") {
|
if (argv[0] === "npm" && argv[1] === "pack") {
|
||||||
packTmpDir = String(typeof opts === "number" ? "" : (opts.cwd ?? ""));
|
packTmpDir = String(typeof opts === "number" ? "" : (opts.cwd ?? ""));
|
||||||
await packToArchive({ pkgDir, outDir: packTmpDir, outName: packedName });
|
fs.writeFileSync(path.join(packTmpDir, packedName), voiceCallArchiveBuffer);
|
||||||
return {
|
return {
|
||||||
code: 0,
|
code: 0,
|
||||||
stdout: JSON.stringify([
|
stdout: JSON.stringify([
|
||||||
|
|||||||
Reference in New Issue
Block a user