From dcf7f8f44c435f0d4d001e1e1637a38de122dd69 Mon Sep 17 00:00:00 2001 From: Shakker Date: Sat, 25 Apr 2026 23:33:50 +0100 Subject: [PATCH] fix: model plugin index records in cli tests --- src/cli/plugins-cli-test-helpers.ts | 38 +++++++++++++++++++-------- src/cli/plugins-cli.uninstall.test.ts | 3 +++ src/cli/plugins-cli.update.test.ts | 4 +++ 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/cli/plugins-cli-test-helpers.ts b/src/cli/plugins-cli-test-helpers.ts index 1cad798baf8..0c0366c9044 100644 --- a/src/cli/plugins-cli-test-helpers.ts +++ b/src/cli/plugins-cli-test-helpers.ts @@ -2,6 +2,7 @@ import { Command } from "commander"; import type { Mock } from "vitest"; import { vi } from "vitest"; import type { OpenClawConfig } from "../config/types.openclaw.js"; +import type { PluginInstallRecord } from "../config/types.plugins.js"; import { createCliRuntimeCapture } from "./test-runtime-capture.js"; type UnknownMock = Mock<(...args: unknown[]) => unknown>; @@ -14,7 +15,13 @@ type ListMarketplacePluginsFn = (typeof import("../plugins/marketplace.js"))["listMarketplacePlugins"]; type ResolveMarketplaceInstallShortcutFn = (typeof import("../plugins/marketplace.js"))["resolveMarketplaceInstallShortcut"]; -type LoadPluginInstallRecordsParams = { config?: OpenClawConfig }; +type PluginInstallRecordMap = Record; + +let mockInstalledPluginIndexInstallRecords: PluginInstallRecordMap = {}; + +function clonePluginInstallRecords(records: PluginInstallRecordMap): PluginInstallRecordMap { + return structuredClone(records); +} // oxlint-disable-next-line typescript/no-unnecessary-type-parameters -- Test helper preserves mock call and result types. function invokeMock(mock: unknown, ...args: TArgs): TResult { @@ -33,14 +40,15 @@ export const listMarketplacePlugins: Mock = vi.fn(); export const resolveMarketplaceInstallShortcut: Mock = vi.fn(); export const enablePluginInConfig: UnknownMock = vi.fn(); export const recordPluginInstall: UnknownMock = vi.fn(); -export const loadInstalledPluginIndexInstallRecords: AsyncUnknownMock = vi.fn( - async (...args: unknown[]) => { - const params = args[0] as LoadPluginInstallRecordsParams | undefined; - return structuredClone(params?.config?.plugins?.installs ?? {}); - }, +export const loadInstalledPluginIndexInstallRecords: AsyncUnknownMock = vi.fn(async () => + clonePluginInstallRecords(mockInstalledPluginIndexInstallRecords), ); export const writePersistedInstalledPluginIndexInstallRecords: AsyncUnknownMock = vi.fn( - async () => undefined, + async (records: unknown) => { + mockInstalledPluginIndexInstallRecords = clonePluginInstallRecords( + (records ?? {}) as PluginInstallRecordMap, + ); + }, ); export const clearPluginManifestRegistryCache: UnknownMock = vi.fn(); export const loadPluginManifestRegistry: UnknownMock = vi.fn(); @@ -69,6 +77,10 @@ const { defaultRuntime, runtimeLogs, runtimeErrors, resetRuntimeCapture } = export { runtimeErrors, runtimeLogs }; +export function setInstalledPluginIndexInstallRecords(records: PluginInstallRecordMap): void { + mockInstalledPluginIndexInstallRecords = clonePluginInstallRecords(records); +} + function restoreRuntimeCaptureMocks() { defaultRuntime.log.mockReset(); defaultRuntime.log.mockImplementation((...args: unknown[]) => { @@ -465,6 +477,7 @@ export function resetPluginsCliTestState() { resolveMarketplaceInstallShortcut.mockReset(); enablePluginInConfig.mockReset(); recordPluginInstall.mockReset(); + mockInstalledPluginIndexInstallRecords = {}; loadInstalledPluginIndexInstallRecords.mockReset(); writePersistedInstalledPluginIndexInstallRecords.mockReset(); clearPluginManifestRegistryCache.mockReset(); @@ -525,11 +538,14 @@ export function resetPluginsCliTestState() { recordPluginInstall.mockImplementation( ((cfg: OpenClawConfig) => cfg) as (...args: unknown[]) => unknown, ); - loadInstalledPluginIndexInstallRecords.mockImplementation(async (...args: unknown[]) => { - const params = args[0] as LoadPluginInstallRecordsParams | undefined; - return structuredClone(params?.config?.plugins?.installs ?? {}); + loadInstalledPluginIndexInstallRecords.mockImplementation(async () => + clonePluginInstallRecords(mockInstalledPluginIndexInstallRecords), + ); + writePersistedInstalledPluginIndexInstallRecords.mockImplementation(async (records: unknown) => { + mockInstalledPluginIndexInstallRecords = clonePluginInstallRecords( + (records ?? {}) as PluginInstallRecordMap, + ); }); - writePersistedInstalledPluginIndexInstallRecords.mockResolvedValue(undefined); loadPluginManifestRegistry.mockReturnValue({ plugins: [], diagnostics: [], diff --git a/src/cli/plugins-cli.uninstall.test.ts b/src/cli/plugins-cli.uninstall.test.ts index 6311d86ff21..c4c17ab14cd 100644 --- a/src/cli/plugins-cli.uninstall.test.ts +++ b/src/cli/plugins-cli.uninstall.test.ts @@ -10,6 +10,7 @@ import { runPluginsCommand, runtimeErrors, runtimeLogs, + setInstalledPluginIndexInstallRecords, uninstallPlugin, writeConfigFile, writePersistedInstalledPluginIndexInstallRecords, @@ -76,6 +77,7 @@ describe("plugins cli uninstall", () => { } as OpenClawConfig; loadConfig.mockReturnValue(baseConfig); + setInstalledPluginIndexInstallRecords(baseConfig.plugins?.installs ?? {}); buildPluginDiagnosticsReport.mockReturnValue({ plugins: [{ id: "alpha", name: "alpha" }], diagnostics: [], @@ -115,6 +117,7 @@ describe("plugins cli uninstall", () => { entries: {}, }, }, + installRecords: {}, reason: "source-changed", }); }); diff --git a/src/cli/plugins-cli.update.test.ts b/src/cli/plugins-cli.update.test.ts index 019c0ddfba6..a29ecfbe174 100644 --- a/src/cli/plugins-cli.update.test.ts +++ b/src/cli/plugins-cli.update.test.ts @@ -9,6 +9,7 @@ import { runPluginsCommand, runtimeErrors, runtimeLogs, + setInstalledPluginIndexInstallRecords, updateNpmInstalledHookPacks, updateNpmInstalledPlugins, writeConfigFile, @@ -147,6 +148,7 @@ describe("plugins cli update", () => { spec: "openclaw-codex-app-server@beta", }); loadConfig.mockReturnValue(config); + setInstalledPluginIndexInstallRecords(config.plugins?.installs ?? {}); updateNpmInstalledPlugins.mockResolvedValue({ config, changed: false, @@ -191,6 +193,7 @@ describe("plugins cli update", () => { }, } as OpenClawConfig; loadConfig.mockReturnValue(cfg); + setInstalledPluginIndexInstallRecords(cfg.plugins?.installs ?? {}); updateNpmInstalledPlugins.mockResolvedValue({ outcomes: [{ status: "ok", message: "Updated alpha -> 1.1.0" }], changed: true, @@ -217,6 +220,7 @@ describe("plugins cli update", () => { expect(writeConfigFile).toHaveBeenCalledWith({}); expect(refreshPluginRegistry).toHaveBeenCalledWith({ config: {}, + installRecords: nextConfig.plugins?.installs, reason: "source-changed", }); expect(