mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-18 09:47:28 +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 JSZip from "jszip";
|
||||
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 {
|
||||
expectSingleNpmInstallIgnoreScriptsCall,
|
||||
@@ -93,14 +93,55 @@ async function createVoiceCallArchive(params: {
|
||||
return { pkgDir, archivePath };
|
||||
}
|
||||
|
||||
async function setupVoiceCallArchiveInstall(params: { outName: string; version: string }) {
|
||||
const stateDir = makeTempDir();
|
||||
async function createVoiceCallArchiveBuffer(version: string): Promise<Buffer> {
|
||||
const workDir = makeTempDir();
|
||||
const { archivePath } = await createVoiceCallArchive({
|
||||
workDir,
|
||||
outName: params.outName,
|
||||
version: params.version,
|
||||
outName: `plugin-${version}.tgz`,
|
||||
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 {
|
||||
stateDir,
|
||||
archivePath,
|
||||
@@ -174,7 +215,7 @@ async function expectArchiveInstallReservedSegmentRejection(params: {
|
||||
expect(result.error).toContain("reserved path segment");
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
afterAll(() => {
|
||||
for (const dir of tempDirs.splice(0)) {
|
||||
try {
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
@@ -238,21 +279,10 @@ describe("installPluginFromArchive", () => {
|
||||
|
||||
it("installs from a zip archive", async () => {
|
||||
const stateDir = makeTempDir();
|
||||
const workDir = makeTempDir();
|
||||
const archivePath = path.join(workDir, "plugin.zip");
|
||||
|
||||
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 archivePath = writeArchiveBuffer({
|
||||
outName: "plugin.zip",
|
||||
buffer: await ZIPPER_ARCHIVE_BUFFER_PROMISE,
|
||||
});
|
||||
|
||||
const extensionsDir = path.join(stateDir, "extensions");
|
||||
const result = await installPluginFromArchive({
|
||||
@@ -270,16 +300,13 @@ describe("installPluginFromArchive", () => {
|
||||
|
||||
it("allows updates when mode is update", async () => {
|
||||
const stateDir = makeTempDir();
|
||||
const workDir = makeTempDir();
|
||||
const { archivePath: archiveV1 } = await createVoiceCallArchive({
|
||||
workDir,
|
||||
const archiveV1 = writeArchiveBuffer({
|
||||
outName: "plugin-v1.tgz",
|
||||
version: "0.0.1",
|
||||
buffer: await VOICE_CALL_ARCHIVE_V1_BUFFER_PROMISE,
|
||||
});
|
||||
const { archivePath: archiveV2 } = await createVoiceCallArchive({
|
||||
workDir,
|
||||
const archiveV2 = writeArchiveBuffer({
|
||||
outName: "plugin-v2.tgz",
|
||||
version: "0.0.2",
|
||||
buffer: await VOICE_CALL_ARCHIVE_V2_BUFFER_PROMISE,
|
||||
});
|
||||
|
||||
const extensionsDir = path.join(stateDir, "extensions");
|
||||
@@ -463,32 +490,20 @@ describe("installPluginFromDir", () => {
|
||||
|
||||
describe("installPluginFromNpmSpec", () => {
|
||||
it("uses --ignore-scripts for npm pack and cleans up temp dir", async () => {
|
||||
const workDir = 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");
|
||||
fs.mkdirSync(extensionsDir, { recursive: true });
|
||||
|
||||
const run = vi.mocked(runCommandWithTimeout);
|
||||
const voiceCallArchiveBuffer = await VOICE_CALL_ARCHIVE_V1_BUFFER_PROMISE;
|
||||
|
||||
let packTmpDir = "";
|
||||
const packedName = "voice-call-0.0.1.tgz";
|
||||
run.mockImplementation(async (argv, opts) => {
|
||||
if (argv[0] === "npm" && argv[1] === "pack") {
|
||||
packTmpDir = String(typeof opts === "number" ? "" : (opts.cwd ?? ""));
|
||||
await packToArchive({ pkgDir, outDir: packTmpDir, outName: packedName });
|
||||
fs.writeFileSync(path.join(packTmpDir, packedName), voiceCallArchiveBuffer);
|
||||
return {
|
||||
code: 0,
|
||||
stdout: JSON.stringify([
|
||||
|
||||
Reference in New Issue
Block a user