






















@@ -1,10 +1,13 @@
1+import fs from "node:fs/promises";
2+import os from "node:os";
13import path from "node:path";
24import { describe, expect, it } from "vitest";
35import {
46buildGatewayInstallEntrypointCandidates as resolveGatewayInstallEntrypointCandidates,
57resolveGatewayInstallEntrypoint,
68} from "../../daemon/gateway-entrypoint.js";
79import {
10+collectMissingPluginInstallPayloads,
811resolvePostInstallDoctorEnv,
912shouldPrepareUpdatedInstallRestart,
1013resolveUpdatedGatewayRestartPort,
@@ -149,6 +152,76 @@ describe("resolvePostInstallDoctorEnv", () => {
149152});
150153});
151154155+describe("collectMissingPluginInstallPayloads", () => {
156+it("reports tracked npm install records whose package payload is absent", async () => {
157+const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-update-plugin-payload-"));
158+const presentDir = path.join(tmpDir, "state", "npm", "node_modules", "@openclaw", "present");
159+const missingDir = path.join(tmpDir, "state", "npm", "node_modules", "@openclaw", "missing");
160+const noPackageJsonDir = path.join(
161+tmpDir,
162+"state",
163+"npm",
164+"node_modules",
165+"@openclaw",
166+"no-package-json",
167+);
168+try {
169+await fs.mkdir(presentDir, { recursive: true });
170+await fs.writeFile(path.join(presentDir, "package.json"), '{"name":"@openclaw/present"}\n');
171+await fs.mkdir(noPackageJsonDir, { recursive: true });
172+173+await expect(
174+collectMissingPluginInstallPayloads({
175+env: { HOME: tmpDir } as NodeJS.ProcessEnv,
176+records: {
177+present: {
178+source: "npm",
179+spec: "@openclaw/present@beta",
180+installPath: presentDir,
181+},
182+missing: {
183+source: "npm",
184+spec: "@openclaw/missing@beta",
185+installPath: missingDir,
186+},
187+"no-package-json": {
188+source: "npm",
189+spec: "@openclaw/no-package-json@beta",
190+installPath: noPackageJsonDir,
191+},
192+"missing-install-path": {
193+source: "npm",
194+spec: "@openclaw/missing-install-path@beta",
195+},
196+local: {
197+source: "path",
198+sourcePath: "/not/checked",
199+installPath: "/not/checked",
200+},
201+},
202+}),
203+).resolves.toEqual([
204+{
205+pluginId: "missing",
206+installPath: missingDir,
207+reason: "missing-package-dir",
208+},
209+{
210+pluginId: "missing-install-path",
211+reason: "missing-install-path",
212+},
213+{
214+pluginId: "no-package-json",
215+installPath: noPackageJsonDir,
216+reason: "missing-package-json",
217+},
218+]);
219+} finally {
220+await fs.rm(tmpDir, { recursive: true, force: true });
221+}
222+});
223+});
224+152225describe("shouldUseLegacyProcessRestartAfterUpdate", () => {
153226it("never restarts package updates through the pre-update process", () => {
154227expect(shouldUseLegacyProcessRestartAfterUpdate({ updateMode: "npm" })).toBe(false);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。