mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 11:27:39 +00:00
test: tighten plugin e2e matrix coverage
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, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, 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,
|
||||||
@@ -16,6 +16,10 @@ vi.mock("../process/exec.js", () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const tempDirs: string[] = [];
|
const tempDirs: string[] = [];
|
||||||
|
let installPluginFromArchive: typeof import("./install.js").installPluginFromArchive;
|
||||||
|
let installPluginFromDir: typeof import("./install.js").installPluginFromDir;
|
||||||
|
let installPluginFromNpmSpec: typeof import("./install.js").installPluginFromNpmSpec;
|
||||||
|
let runCommandWithTimeout: typeof import("../process/exec.js").runCommandWithTimeout;
|
||||||
|
|
||||||
function makeTempDir() {
|
function makeTempDir() {
|
||||||
const dir = path.join(os.tmpdir(), `openclaw-plugin-install-${randomUUID()}`);
|
const dir = path.join(os.tmpdir(), `openclaw-plugin-install-${randomUUID()}`);
|
||||||
@@ -120,7 +124,6 @@ function setupPluginInstallDirs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function installFromDirWithWarnings(params: { pluginDir: string; extensionsDir: string }) {
|
async function installFromDirWithWarnings(params: { pluginDir: string; extensionsDir: string }) {
|
||||||
const { installPluginFromDir } = await import("./install.js");
|
|
||||||
const warnings: string[] = [];
|
const warnings: string[] = [];
|
||||||
const result = await installPluginFromDir({
|
const result = await installPluginFromDir({
|
||||||
dirPath: params.pluginDir,
|
dirPath: params.pluginDir,
|
||||||
@@ -159,7 +162,6 @@ async function expectArchiveInstallReservedSegmentRejection(params: {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const extensionsDir = path.join(stateDir, "extensions");
|
const extensionsDir = path.join(stateDir, "extensions");
|
||||||
const { installPluginFromArchive } = await import("./install.js");
|
|
||||||
const result = await installPluginFromArchive({
|
const result = await installPluginFromArchive({
|
||||||
archivePath,
|
archivePath,
|
||||||
extensionsDir,
|
extensionsDir,
|
||||||
@@ -182,6 +184,12 @@ afterEach(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
({ installPluginFromArchive, installPluginFromDir, installPluginFromNpmSpec } =
|
||||||
|
await import("./install.js"));
|
||||||
|
({ runCommandWithTimeout } = await import("../process/exec.js"));
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
});
|
});
|
||||||
@@ -193,7 +201,6 @@ describe("installPluginFromArchive", () => {
|
|||||||
version: "0.0.1",
|
version: "0.0.1",
|
||||||
});
|
});
|
||||||
|
|
||||||
const { installPluginFromArchive } = await import("./install.js");
|
|
||||||
const result = await installPluginFromArchive({
|
const result = await installPluginFromArchive({
|
||||||
archivePath,
|
archivePath,
|
||||||
extensionsDir,
|
extensionsDir,
|
||||||
@@ -212,7 +219,6 @@ describe("installPluginFromArchive", () => {
|
|||||||
version: "0.0.1",
|
version: "0.0.1",
|
||||||
});
|
});
|
||||||
|
|
||||||
const { installPluginFromArchive } = await import("./install.js");
|
|
||||||
const first = await installPluginFromArchive({
|
const first = await installPluginFromArchive({
|
||||||
archivePath,
|
archivePath,
|
||||||
extensionsDir,
|
extensionsDir,
|
||||||
@@ -249,7 +255,6 @@ describe("installPluginFromArchive", () => {
|
|||||||
fs.writeFileSync(archivePath, buffer);
|
fs.writeFileSync(archivePath, buffer);
|
||||||
|
|
||||||
const extensionsDir = path.join(stateDir, "extensions");
|
const extensionsDir = path.join(stateDir, "extensions");
|
||||||
const { installPluginFromArchive } = await import("./install.js");
|
|
||||||
const result = await installPluginFromArchive({
|
const result = await installPluginFromArchive({
|
||||||
archivePath,
|
archivePath,
|
||||||
extensionsDir,
|
extensionsDir,
|
||||||
@@ -278,7 +283,6 @@ describe("installPluginFromArchive", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const extensionsDir = path.join(stateDir, "extensions");
|
const extensionsDir = path.join(stateDir, "extensions");
|
||||||
const { installPluginFromArchive } = await import("./install.js");
|
|
||||||
const first = await installPluginFromArchive({
|
const first = await installPluginFromArchive({
|
||||||
archivePath: archiveV1,
|
archivePath: archiveV1,
|
||||||
extensionsDir,
|
extensionsDir,
|
||||||
@@ -332,7 +336,6 @@ describe("installPluginFromArchive", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const extensionsDir = path.join(stateDir, "extensions");
|
const extensionsDir = path.join(stateDir, "extensions");
|
||||||
const { installPluginFromArchive } = await import("./install.js");
|
|
||||||
const result = await installPluginFromArchive({
|
const result = await installPluginFromArchive({
|
||||||
archivePath,
|
archivePath,
|
||||||
extensionsDir,
|
extensionsDir,
|
||||||
@@ -433,7 +436,6 @@ describe("installPluginFromDir", () => {
|
|||||||
);
|
);
|
||||||
fs.writeFileSync(path.join(pluginDir, "dist", "index.js"), "export {};", "utf-8");
|
fs.writeFileSync(path.join(pluginDir, "dist", "index.js"), "export {};", "utf-8");
|
||||||
|
|
||||||
const { runCommandWithTimeout } = await import("../process/exec.js");
|
|
||||||
const run = vi.mocked(runCommandWithTimeout);
|
const run = vi.mocked(runCommandWithTimeout);
|
||||||
run.mockResolvedValue({
|
run.mockResolvedValue({
|
||||||
code: 0,
|
code: 0,
|
||||||
@@ -444,7 +446,6 @@ describe("installPluginFromDir", () => {
|
|||||||
termination: "exit",
|
termination: "exit",
|
||||||
});
|
});
|
||||||
|
|
||||||
const { installPluginFromDir } = await import("./install.js");
|
|
||||||
const res = await installPluginFromDir({
|
const res = await installPluginFromDir({
|
||||||
dirPath: pluginDir,
|
dirPath: pluginDir,
|
||||||
extensionsDir: path.join(stateDir, "extensions"),
|
extensionsDir: path.join(stateDir, "extensions"),
|
||||||
@@ -480,7 +481,6 @@ describe("installPluginFromNpmSpec", () => {
|
|||||||
const extensionsDir = path.join(stateDir, "extensions");
|
const extensionsDir = path.join(stateDir, "extensions");
|
||||||
fs.mkdirSync(extensionsDir, { recursive: true });
|
fs.mkdirSync(extensionsDir, { recursive: true });
|
||||||
|
|
||||||
const { runCommandWithTimeout } = await import("../process/exec.js");
|
|
||||||
const run = vi.mocked(runCommandWithTimeout);
|
const run = vi.mocked(runCommandWithTimeout);
|
||||||
|
|
||||||
let packTmpDir = "";
|
let packTmpDir = "";
|
||||||
@@ -510,7 +510,6 @@ describe("installPluginFromNpmSpec", () => {
|
|||||||
throw new Error(`unexpected command: ${argv.join(" ")}`);
|
throw new Error(`unexpected command: ${argv.join(" ")}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
const { installPluginFromNpmSpec } = await import("./install.js");
|
|
||||||
const result = await installPluginFromNpmSpec({
|
const result = await installPluginFromNpmSpec({
|
||||||
spec: "@openclaw/voice-call@0.0.1",
|
spec: "@openclaw/voice-call@0.0.1",
|
||||||
extensionsDir,
|
extensionsDir,
|
||||||
@@ -533,7 +532,6 @@ describe("installPluginFromNpmSpec", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("rejects non-registry npm specs", async () => {
|
it("rejects non-registry npm specs", async () => {
|
||||||
const { installPluginFromNpmSpec } = await import("./install.js");
|
|
||||||
const result = await installPluginFromNpmSpec({ spec: "github:evil/evil" });
|
const result = await installPluginFromNpmSpec({ spec: "github:evil/evil" });
|
||||||
expect(result.ok).toBe(false);
|
expect(result.ok).toBe(false);
|
||||||
if (result.ok) {
|
if (result.ok) {
|
||||||
@@ -543,7 +541,6 @@ describe("installPluginFromNpmSpec", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("aborts when integrity drift callback rejects the fetched artifact", async () => {
|
it("aborts when integrity drift callback rejects the fetched artifact", async () => {
|
||||||
const { runCommandWithTimeout } = await import("../process/exec.js");
|
|
||||||
const run = vi.mocked(runCommandWithTimeout);
|
const run = vi.mocked(runCommandWithTimeout);
|
||||||
run.mockResolvedValue({
|
run.mockResolvedValue({
|
||||||
code: 0,
|
code: 0,
|
||||||
@@ -564,7 +561,6 @@ describe("installPluginFromNpmSpec", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const onIntegrityDrift = vi.fn(async () => false);
|
const onIntegrityDrift = vi.fn(async () => false);
|
||||||
const { installPluginFromNpmSpec } = await import("./install.js");
|
|
||||||
const result = await installPluginFromNpmSpec({
|
const result = await installPluginFromNpmSpec({
|
||||||
spec: "@openclaw/voice-call@0.0.1",
|
spec: "@openclaw/voice-call@0.0.1",
|
||||||
expectedIntegrity: "sha512-old",
|
expectedIntegrity: "sha512-old",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Test: after_tool_call hook wiring (pi-embedded-subscribe.handlers.tools.ts)
|
* Test: after_tool_call hook wiring (pi-embedded-subscribe.handlers.tools.ts)
|
||||||
*/
|
*/
|
||||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
const hookMocks = vi.hoisted(() => ({
|
const hookMocks = vi.hoisted(() => ({
|
||||||
runner: {
|
runner: {
|
||||||
@@ -58,7 +58,15 @@ function createToolHandlerCtx(params: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let handleToolExecutionStart: typeof import("../agents/pi-embedded-subscribe.handlers.tools.js").handleToolExecutionStart;
|
||||||
|
let handleToolExecutionEnd: typeof import("../agents/pi-embedded-subscribe.handlers.tools.js").handleToolExecutionEnd;
|
||||||
|
|
||||||
describe("after_tool_call hook wiring", () => {
|
describe("after_tool_call hook wiring", () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
({ handleToolExecutionStart, handleToolExecutionEnd } =
|
||||||
|
await import("../agents/pi-embedded-subscribe.handlers.tools.js"));
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
hookMocks.runner.hasHooks.mockReset();
|
hookMocks.runner.hasHooks.mockReset();
|
||||||
hookMocks.runner.hasHooks.mockReturnValue(false);
|
hookMocks.runner.hasHooks.mockReturnValue(false);
|
||||||
@@ -71,9 +79,6 @@ describe("after_tool_call hook wiring", () => {
|
|||||||
it("calls runAfterToolCall in handleToolExecutionEnd when hook is registered", async () => {
|
it("calls runAfterToolCall in handleToolExecutionEnd when hook is registered", async () => {
|
||||||
hookMocks.runner.hasHooks.mockReturnValue(true);
|
hookMocks.runner.hasHooks.mockReturnValue(true);
|
||||||
|
|
||||||
const { handleToolExecutionEnd, handleToolExecutionStart } =
|
|
||||||
await import("../agents/pi-embedded-subscribe.handlers.tools.js");
|
|
||||||
|
|
||||||
const ctx = createToolHandlerCtx({
|
const ctx = createToolHandlerCtx({
|
||||||
runId: "test-run-1",
|
runId: "test-run-1",
|
||||||
agentId: "main",
|
agentId: "main",
|
||||||
@@ -125,9 +130,6 @@ describe("after_tool_call hook wiring", () => {
|
|||||||
it("includes error in after_tool_call event on tool failure", async () => {
|
it("includes error in after_tool_call event on tool failure", async () => {
|
||||||
hookMocks.runner.hasHooks.mockReturnValue(true);
|
hookMocks.runner.hasHooks.mockReturnValue(true);
|
||||||
|
|
||||||
const { handleToolExecutionEnd, handleToolExecutionStart } =
|
|
||||||
await import("../agents/pi-embedded-subscribe.handlers.tools.js");
|
|
||||||
|
|
||||||
const ctx = createToolHandlerCtx({ runId: "test-run-2" });
|
const ctx = createToolHandlerCtx({ runId: "test-run-2" });
|
||||||
|
|
||||||
await handleToolExecutionStart(
|
await handleToolExecutionStart(
|
||||||
@@ -166,9 +168,6 @@ describe("after_tool_call hook wiring", () => {
|
|||||||
it("does not call runAfterToolCall when no hooks registered", async () => {
|
it("does not call runAfterToolCall when no hooks registered", async () => {
|
||||||
hookMocks.runner.hasHooks.mockReturnValue(false);
|
hookMocks.runner.hasHooks.mockReturnValue(false);
|
||||||
|
|
||||||
const { handleToolExecutionEnd } =
|
|
||||||
await import("../agents/pi-embedded-subscribe.handlers.tools.js");
|
|
||||||
|
|
||||||
const ctx = createToolHandlerCtx({ runId: "r" });
|
const ctx = createToolHandlerCtx({ runId: "r" });
|
||||||
|
|
||||||
await handleToolExecutionEnd(
|
await handleToolExecutionEnd(
|
||||||
|
|||||||
Reference in New Issue
Block a user