test: tighten plugin e2e matrix coverage

This commit is contained in:
Peter Steinberger
2026-02-21 21:43:22 +00:00
parent cc2ff68947
commit 5c8f0b5a77
2 changed files with 20 additions and 25 deletions

View File

@@ -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, 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 {
expectSingleNpmInstallIgnoreScriptsCall,
@@ -16,6 +16,10 @@ vi.mock("../process/exec.js", () => ({
}));
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() {
const dir = path.join(os.tmpdir(), `openclaw-plugin-install-${randomUUID()}`);
@@ -120,7 +124,6 @@ function setupPluginInstallDirs() {
}
async function installFromDirWithWarnings(params: { pluginDir: string; extensionsDir: string }) {
const { installPluginFromDir } = await import("./install.js");
const warnings: string[] = [];
const result = await installPluginFromDir({
dirPath: params.pluginDir,
@@ -159,7 +162,6 @@ async function expectArchiveInstallReservedSegmentRejection(params: {
});
const extensionsDir = path.join(stateDir, "extensions");
const { installPluginFromArchive } = await import("./install.js");
const result = await installPluginFromArchive({
archivePath,
extensionsDir,
@@ -182,6 +184,12 @@ afterEach(() => {
}
});
beforeAll(async () => {
({ installPluginFromArchive, installPluginFromDir, installPluginFromNpmSpec } =
await import("./install.js"));
({ runCommandWithTimeout } = await import("../process/exec.js"));
});
beforeEach(() => {
vi.clearAllMocks();
});
@@ -193,7 +201,6 @@ describe("installPluginFromArchive", () => {
version: "0.0.1",
});
const { installPluginFromArchive } = await import("./install.js");
const result = await installPluginFromArchive({
archivePath,
extensionsDir,
@@ -212,7 +219,6 @@ describe("installPluginFromArchive", () => {
version: "0.0.1",
});
const { installPluginFromArchive } = await import("./install.js");
const first = await installPluginFromArchive({
archivePath,
extensionsDir,
@@ -249,7 +255,6 @@ describe("installPluginFromArchive", () => {
fs.writeFileSync(archivePath, buffer);
const extensionsDir = path.join(stateDir, "extensions");
const { installPluginFromArchive } = await import("./install.js");
const result = await installPluginFromArchive({
archivePath,
extensionsDir,
@@ -278,7 +283,6 @@ describe("installPluginFromArchive", () => {
});
const extensionsDir = path.join(stateDir, "extensions");
const { installPluginFromArchive } = await import("./install.js");
const first = await installPluginFromArchive({
archivePath: archiveV1,
extensionsDir,
@@ -332,7 +336,6 @@ describe("installPluginFromArchive", () => {
});
const extensionsDir = path.join(stateDir, "extensions");
const { installPluginFromArchive } = await import("./install.js");
const result = await installPluginFromArchive({
archivePath,
extensionsDir,
@@ -433,7 +436,6 @@ describe("installPluginFromDir", () => {
);
fs.writeFileSync(path.join(pluginDir, "dist", "index.js"), "export {};", "utf-8");
const { runCommandWithTimeout } = await import("../process/exec.js");
const run = vi.mocked(runCommandWithTimeout);
run.mockResolvedValue({
code: 0,
@@ -444,7 +446,6 @@ describe("installPluginFromDir", () => {
termination: "exit",
});
const { installPluginFromDir } = await import("./install.js");
const res = await installPluginFromDir({
dirPath: pluginDir,
extensionsDir: path.join(stateDir, "extensions"),
@@ -480,7 +481,6 @@ describe("installPluginFromNpmSpec", () => {
const extensionsDir = path.join(stateDir, "extensions");
fs.mkdirSync(extensionsDir, { recursive: true });
const { runCommandWithTimeout } = await import("../process/exec.js");
const run = vi.mocked(runCommandWithTimeout);
let packTmpDir = "";
@@ -510,7 +510,6 @@ describe("installPluginFromNpmSpec", () => {
throw new Error(`unexpected command: ${argv.join(" ")}`);
});
const { installPluginFromNpmSpec } = await import("./install.js");
const result = await installPluginFromNpmSpec({
spec: "@openclaw/voice-call@0.0.1",
extensionsDir,
@@ -533,7 +532,6 @@ describe("installPluginFromNpmSpec", () => {
});
it("rejects non-registry npm specs", async () => {
const { installPluginFromNpmSpec } = await import("./install.js");
const result = await installPluginFromNpmSpec({ spec: "github:evil/evil" });
expect(result.ok).toBe(false);
if (result.ok) {
@@ -543,7 +541,6 @@ describe("installPluginFromNpmSpec", () => {
});
it("aborts when integrity drift callback rejects the fetched artifact", async () => {
const { runCommandWithTimeout } = await import("../process/exec.js");
const run = vi.mocked(runCommandWithTimeout);
run.mockResolvedValue({
code: 0,
@@ -564,7 +561,6 @@ describe("installPluginFromNpmSpec", () => {
});
const onIntegrityDrift = vi.fn(async () => false);
const { installPluginFromNpmSpec } = await import("./install.js");
const result = await installPluginFromNpmSpec({
spec: "@openclaw/voice-call@0.0.1",
expectedIntegrity: "sha512-old",

View File

@@ -1,7 +1,7 @@
/**
* 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(() => ({
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", () => {
beforeAll(async () => {
({ handleToolExecutionStart, handleToolExecutionEnd } =
await import("../agents/pi-embedded-subscribe.handlers.tools.js"));
});
beforeEach(() => {
hookMocks.runner.hasHooks.mockReset();
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 () => {
hookMocks.runner.hasHooks.mockReturnValue(true);
const { handleToolExecutionEnd, handleToolExecutionStart } =
await import("../agents/pi-embedded-subscribe.handlers.tools.js");
const ctx = createToolHandlerCtx({
runId: "test-run-1",
agentId: "main",
@@ -125,9 +130,6 @@ describe("after_tool_call hook wiring", () => {
it("includes error in after_tool_call event on tool failure", async () => {
hookMocks.runner.hasHooks.mockReturnValue(true);
const { handleToolExecutionEnd, handleToolExecutionStart } =
await import("../agents/pi-embedded-subscribe.handlers.tools.js");
const ctx = createToolHandlerCtx({ runId: "test-run-2" });
await handleToolExecutionStart(
@@ -166,9 +168,6 @@ describe("after_tool_call hook wiring", () => {
it("does not call runAfterToolCall when no hooks registered", async () => {
hookMocks.runner.hasHooks.mockReturnValue(false);
const { handleToolExecutionEnd } =
await import("../agents/pi-embedded-subscribe.handlers.tools.js");
const ctx = createToolHandlerCtx({ runId: "r" });
await handleToolExecutionEnd(