





















@@ -2,6 +2,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
2233const mocks = vi.hoisted(() => ({
44detectPluginAutoEnableCandidates: vi.fn(),
5+getOfficialExternalPluginCatalogEntry: vi.fn(),
56repairMissingPluginInstallsForIds: vi.fn(),
67resolveProviderInstallCatalogEntries: vi.fn(),
78}));
@@ -14,6 +15,14 @@ vi.mock("../../../plugins/provider-install-catalog.js", () => ({
1415resolveProviderInstallCatalogEntries: mocks.resolveProviderInstallCatalogEntries,
1516}));
161718+vi.mock(import("../../../plugins/official-external-plugin-catalog.js"), async (importOriginal) => {
19+const actual = await importOriginal();
20+return {
21+ ...actual,
22+getOfficialExternalPluginCatalogEntry: mocks.getOfficialExternalPluginCatalogEntry,
23+};
24+});
25+1726vi.mock("./missing-configured-plugin-install.js", () => ({
1827repairMissingPluginInstallsForIds: mocks.repairMissingPluginInstallsForIds,
1928}));
@@ -22,6 +31,7 @@ describe("configured plugin install release step", () => {
2231beforeEach(() => {
2332vi.clearAllMocks();
2433mocks.detectPluginAutoEnableCandidates.mockReturnValue([]);
34+mocks.getOfficialExternalPluginCatalogEntry.mockReturnValue(undefined);
2535mocks.resolveProviderInstallCatalogEntries.mockReturnValue([]);
2636mocks.repairMissingPluginInstallsForIds.mockResolvedValue({
2737changes: [],
@@ -372,4 +382,53 @@ describe("configured plugin install release step", () => {
372382touchedConfig: false,
373383});
374384});
385+386+it("includes allow-only official plugin ids in the repair set", async () => {
387+mocks.getOfficialExternalPluginCatalogEntry.mockImplementation((pluginId: string) => {
388+if (pluginId === "lobster") {
389+return { name: "@openclaw/lobster" };
390+}
391+return undefined;
392+});
393+394+const { collectReleaseConfiguredPluginIds } =
395+await import("./release-configured-plugin-installs.js");
396+const result = collectReleaseConfiguredPluginIds({
397+cfg: {
398+plugins: {
399+allow: ["lobster", "unofficial-custom"],
400+},
401+},
402+env: {},
403+});
404+405+expect(result.pluginIds).toEqual(["lobster"]);
406+expect(result.channelIds).toEqual([]);
407+});
408+409+it("skips allow-only plugin ids that already have material plugin entries", async () => {
410+mocks.getOfficialExternalPluginCatalogEntry.mockImplementation((pluginId: string) => {
411+if (pluginId === "lobster") {
412+return { name: "@openclaw/lobster" };
413+}
414+return undefined;
415+});
416+417+const { collectReleaseConfiguredPluginIds } =
418+await import("./release-configured-plugin-installs.js");
419+const result = collectReleaseConfiguredPluginIds({
420+cfg: {
421+plugins: {
422+allow: ["lobster"],
423+entries: {
424+lobster: { enabled: true },
425+},
426+},
427+},
428+env: {},
429+});
430+431+expect(result.pluginIds).toEqual(["lobster"]);
432+expect(mocks.getOfficialExternalPluginCatalogEntry).not.toHaveBeenCalledWith("lobster");
433+});
375434});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。