mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:00:43 +00:00
fix: align plugin install tests with ledger store
This commit is contained in:
@@ -14,6 +14,7 @@ type ListMarketplacePluginsFn =
|
||||
(typeof import("../plugins/marketplace.js"))["listMarketplacePlugins"];
|
||||
type ResolveMarketplaceInstallShortcutFn =
|
||||
(typeof import("../plugins/marketplace.js"))["resolveMarketplaceInstallShortcut"];
|
||||
type LoadPluginInstallRecordsParams = { config?: OpenClawConfig };
|
||||
|
||||
// oxlint-disable-next-line typescript/no-unnecessary-type-parameters -- Test helper preserves mock call and result types.
|
||||
function invokeMock<TArgs extends unknown[], TResult>(mock: unknown, ...args: TArgs): TResult {
|
||||
@@ -32,9 +33,9 @@ export const listMarketplacePlugins: Mock<ListMarketplacePluginsFn> = vi.fn();
|
||||
export const resolveMarketplaceInstallShortcut: Mock<ResolveMarketplaceInstallShortcutFn> = vi.fn();
|
||||
export const enablePluginInConfig: UnknownMock = vi.fn();
|
||||
export const recordPluginInstall: UnknownMock = vi.fn();
|
||||
export const loadPluginInstallRecords: AsyncUnknownMock = vi.fn(async ({ config }) => {
|
||||
const cfg = config as OpenClawConfig | undefined;
|
||||
return structuredClone(cfg?.plugins?.installs ?? {});
|
||||
export const loadPluginInstallRecords: AsyncUnknownMock = vi.fn(async (...args: unknown[]) => {
|
||||
const params = args[0] as LoadPluginInstallRecordsParams | undefined;
|
||||
return structuredClone(params?.config?.plugins?.installs ?? {});
|
||||
});
|
||||
export const writePersistedPluginInstallLedger: AsyncUnknownMock = vi.fn(async () => undefined);
|
||||
export const clearPluginManifestRegistryCache: UnknownMock = vi.fn();
|
||||
@@ -518,9 +519,9 @@ export function resetPluginsCliTestState() {
|
||||
recordPluginInstall.mockImplementation(
|
||||
((cfg: OpenClawConfig) => cfg) as (...args: unknown[]) => unknown,
|
||||
);
|
||||
loadPluginInstallRecords.mockImplementation(async ({ config }) => {
|
||||
const cfg = config as OpenClawConfig | undefined;
|
||||
return structuredClone(cfg?.plugins?.installs ?? {});
|
||||
loadPluginInstallRecords.mockImplementation(async (...args: unknown[]) => {
|
||||
const params = args[0] as LoadPluginInstallRecordsParams | undefined;
|
||||
return structuredClone(params?.config?.plugins?.installs ?? {});
|
||||
});
|
||||
writePersistedPluginInstallLedger.mockResolvedValue(undefined);
|
||||
loadPluginManifestRegistry.mockReturnValue({
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
runtimeErrors,
|
||||
runtimeLogs,
|
||||
writeConfigFile,
|
||||
writePersistedPluginInstallLedger,
|
||||
} from "./plugins-cli-test-helpers.js";
|
||||
|
||||
const CLI_STATE_ROOT = "/tmp/openclaw-state";
|
||||
@@ -53,22 +54,6 @@ function createEmptyPluginConfig(): OpenClawConfig {
|
||||
} as OpenClawConfig;
|
||||
}
|
||||
|
||||
function createClawHubInstalledConfig(params: {
|
||||
pluginId: string;
|
||||
install: Record<string, unknown>;
|
||||
}): OpenClawConfig {
|
||||
const enabledCfg = createEnabledPluginConfig(params.pluginId);
|
||||
return {
|
||||
...enabledCfg,
|
||||
plugins: {
|
||||
...enabledCfg.plugins,
|
||||
installs: {
|
||||
[params.pluginId]: params.install,
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
}
|
||||
|
||||
function createClawHubInstallResult(params: {
|
||||
pluginId: string;
|
||||
packageName: string;
|
||||
@@ -320,19 +305,6 @@ describe("plugins cli install", () => {
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
const installedCfg = {
|
||||
...enabledCfg,
|
||||
plugins: {
|
||||
...enabledCfg.plugins,
|
||||
installs: {
|
||||
alpha: {
|
||||
source: "marketplace",
|
||||
installPath: cliInstallPath("alpha"),
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
|
||||
loadConfig.mockReturnValue(cfg);
|
||||
installPluginFromMarketplace.mockResolvedValue({
|
||||
ok: true,
|
||||
@@ -345,20 +317,25 @@ describe("plugins cli install", () => {
|
||||
marketplacePlugin: "alpha",
|
||||
});
|
||||
enablePluginInConfig.mockReturnValue({ config: enabledCfg });
|
||||
recordPluginInstall.mockReturnValue(installedCfg);
|
||||
buildPluginDiagnosticsReport.mockReturnValue({
|
||||
plugins: [{ id: "alpha", kind: "provider" }],
|
||||
diagnostics: [],
|
||||
});
|
||||
applyExclusiveSlotSelection.mockReturnValue({
|
||||
config: installedCfg,
|
||||
config: enabledCfg,
|
||||
warnings: ["slot adjusted"],
|
||||
});
|
||||
|
||||
await runPluginsCommand(["plugins", "install", "alpha", "--marketplace", "local/repo"]);
|
||||
|
||||
expect(clearPluginManifestRegistryCache).toHaveBeenCalledTimes(1);
|
||||
expect(writeConfigFile).toHaveBeenCalledWith(installedCfg);
|
||||
expect(writePersistedPluginInstallLedger).toHaveBeenCalledWith({
|
||||
alpha: expect.objectContaining({
|
||||
source: "marketplace",
|
||||
installPath: cliInstallPath("alpha"),
|
||||
}),
|
||||
});
|
||||
expect(writeConfigFile).toHaveBeenCalledWith(enabledCfg);
|
||||
expect(runtimeLogs.some((line) => line.includes("slot adjusted"))).toBe(true);
|
||||
expect(runtimeLogs.some((line) => line.includes("Installed plugin: alpha"))).toBe(true);
|
||||
});
|
||||
@@ -384,18 +361,6 @@ describe("plugins cli install", () => {
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
const enabledCfg = createEnabledPluginConfig("demo");
|
||||
const installedCfg = createClawHubInstalledConfig({
|
||||
pluginId: "demo",
|
||||
install: {
|
||||
source: "clawhub",
|
||||
spec: "clawhub:demo@1.2.3",
|
||||
installPath: cliInstallPath("demo"),
|
||||
clawhubPackage: "demo",
|
||||
clawhubFamily: "code-plugin",
|
||||
clawhubChannel: "official",
|
||||
},
|
||||
});
|
||||
|
||||
loadConfig.mockReturnValue(cfg);
|
||||
parseClawHubPluginSpec.mockReturnValue({ name: "demo" });
|
||||
installPluginFromClawHub.mockResolvedValue(
|
||||
@@ -407,9 +372,8 @@ describe("plugins cli install", () => {
|
||||
}),
|
||||
);
|
||||
enablePluginInConfig.mockReturnValue({ config: enabledCfg });
|
||||
recordPluginInstall.mockReturnValue(installedCfg);
|
||||
applyExclusiveSlotSelection.mockReturnValue({
|
||||
config: installedCfg,
|
||||
config: enabledCfg,
|
||||
warnings: [],
|
||||
});
|
||||
|
||||
@@ -420,18 +384,16 @@ describe("plugins cli install", () => {
|
||||
spec: "clawhub:demo",
|
||||
}),
|
||||
);
|
||||
expect(recordPluginInstall).toHaveBeenCalledWith(
|
||||
enabledCfg,
|
||||
expect.objectContaining({
|
||||
pluginId: "demo",
|
||||
expect(writePersistedPluginInstallLedger).toHaveBeenCalledWith({
|
||||
demo: expect.objectContaining({
|
||||
source: "clawhub",
|
||||
spec: "clawhub:demo@1.2.3",
|
||||
clawhubPackage: "demo",
|
||||
clawhubFamily: "code-plugin",
|
||||
clawhubChannel: "official",
|
||||
}),
|
||||
);
|
||||
expect(writeConfigFile).toHaveBeenCalledWith(installedCfg);
|
||||
});
|
||||
expect(writeConfigFile).toHaveBeenCalledWith(enabledCfg);
|
||||
expect(runtimeLogs.some((line) => line.includes("Installed plugin: demo"))).toBe(true);
|
||||
expect(installPluginFromNpmSpec).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -478,16 +440,6 @@ describe("plugins cli install", () => {
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
const enabledCfg = createEnabledPluginConfig("demo");
|
||||
const installedCfg = createClawHubInstalledConfig({
|
||||
pluginId: "demo",
|
||||
install: {
|
||||
source: "clawhub",
|
||||
spec: "clawhub:demo@1.2.3",
|
||||
installPath: cliInstallPath("demo"),
|
||||
clawhubPackage: "demo",
|
||||
},
|
||||
});
|
||||
|
||||
loadConfig.mockReturnValue(cfg);
|
||||
installPluginFromClawHub.mockResolvedValue(
|
||||
createClawHubInstallResult({
|
||||
@@ -498,9 +450,8 @@ describe("plugins cli install", () => {
|
||||
}),
|
||||
);
|
||||
enablePluginInConfig.mockReturnValue({ config: enabledCfg });
|
||||
recordPluginInstall.mockReturnValue(installedCfg);
|
||||
applyExclusiveSlotSelection.mockReturnValue({
|
||||
config: installedCfg,
|
||||
config: enabledCfg,
|
||||
warnings: [],
|
||||
});
|
||||
|
||||
@@ -512,7 +463,14 @@ describe("plugins cli install", () => {
|
||||
}),
|
||||
);
|
||||
expect(installPluginFromNpmSpec).not.toHaveBeenCalled();
|
||||
expect(writeConfigFile).toHaveBeenCalledWith(installedCfg);
|
||||
expect(writePersistedPluginInstallLedger).toHaveBeenCalledWith({
|
||||
demo: expect.objectContaining({
|
||||
source: "clawhub",
|
||||
spec: "clawhub:demo@1.2.3",
|
||||
clawhubPackage: "demo",
|
||||
}),
|
||||
});
|
||||
expect(writeConfigFile).toHaveBeenCalledWith(enabledCfg);
|
||||
});
|
||||
|
||||
it("falls back to npm when ClawHub does not have the package", async () => {
|
||||
|
||||
@@ -2,6 +2,7 @@ import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import type { PluginInstallRecord } from "../config/types.plugins.js";
|
||||
import {
|
||||
loadPluginInstallRecords,
|
||||
loadPluginInstallRecordsSync,
|
||||
@@ -127,7 +128,7 @@ describe("plugin install ledger store", () => {
|
||||
source: "npm",
|
||||
spec: "keep@1.0.0",
|
||||
},
|
||||
};
|
||||
} satisfies Record<string, PluginInstallRecord>;
|
||||
const withInstall = recordPluginInstallInRecords(records, {
|
||||
pluginId: "demo",
|
||||
source: "npm",
|
||||
|
||||
Reference in New Issue
Block a user