






























@@ -0,0 +1,83 @@
1+import { beforeEach, describe, expect, it, vi } from "vitest";
2+import type { OpenClawConfig } from "../config/types.openclaw.js";
3+4+const mocks = vi.hoisted(() => ({
5+applyPluginAutoEnable: vi.fn(),
6+getCurrentPluginMetadataSnapshot: vi.fn(),
7+}));
8+9+vi.mock("../config/plugin-auto-enable.js", () => ({
10+applyPluginAutoEnable: mocks.applyPluginAutoEnable,
11+}));
12+13+vi.mock("../plugins/current-plugin-metadata-snapshot.js", () => ({
14+getCurrentPluginMetadataSnapshot: mocks.getCurrentPluginMetadataSnapshot,
15+}));
16+17+describe("resolveGatewayPluginConfig", () => {
18+beforeEach(() => {
19+mocks.applyPluginAutoEnable.mockReset();
20+mocks.getCurrentPluginMetadataSnapshot.mockReset();
21+});
22+23+it("reuses auto-enabled config for the same runtime config and metadata snapshot", async () => {
24+const { resolveGatewayPluginConfig } = await import("./runtime-plugin-config.js");
25+const config = { channels: { telegram: { botToken: "token" } } } as OpenClawConfig;
26+const snapshot = { manifestRegistry: { plugins: [], diagnostics: [] } };
27+const resolved = { ...config, plugins: { allow: ["telegram"] } } as OpenClawConfig;
28+mocks.getCurrentPluginMetadataSnapshot.mockReturnValue(snapshot);
29+mocks.applyPluginAutoEnable.mockReturnValue({ config: resolved, changes: [] });
30+31+expect(resolveGatewayPluginConfig({ config })).toBe(resolved);
32+expect(resolveGatewayPluginConfig({ config })).toBe(resolved);
33+34+expect(mocks.applyPluginAutoEnable).toHaveBeenCalledTimes(1);
35+});
36+37+it("refreshes the cached config when metadata snapshot changes", async () => {
38+const { resolveGatewayPluginConfig } = await import("./runtime-plugin-config.js");
39+const config = { channels: { telegram: { botToken: "token" } } } as OpenClawConfig;
40+const first = { manifestRegistry: { plugins: [], diagnostics: [] } };
41+const second = { manifestRegistry: { plugins: [], diagnostics: [] } };
42+mocks.getCurrentPluginMetadataSnapshot.mockReturnValueOnce(first).mockReturnValue(second);
43+mocks.applyPluginAutoEnable
44+.mockReturnValueOnce({ config: { ...config, first: true }, changes: [] })
45+.mockReturnValueOnce({ config: { ...config, second: true }, changes: [] });
46+47+expect(resolveGatewayPluginConfig({ config })).toMatchObject({ first: true });
48+expect(resolveGatewayPluginConfig({ config })).toMatchObject({ second: true });
49+50+expect(mocks.applyPluginAutoEnable).toHaveBeenCalledTimes(2);
51+});
52+53+it("refreshes the cached config when env object changes", async () => {
54+const { resolveGatewayPluginConfig } = await import("./runtime-plugin-config.js");
55+const config = { channels: { telegram: { botToken: "token" } } } as OpenClawConfig;
56+const snapshot = { manifestRegistry: { plugins: [], diagnostics: [] } };
57+mocks.getCurrentPluginMetadataSnapshot.mockReturnValue(snapshot);
58+mocks.applyPluginAutoEnable
59+.mockReturnValueOnce({ config: { ...config, first: true }, changes: [] })
60+.mockReturnValueOnce({ config: { ...config, second: true }, changes: [] });
61+62+expect(resolveGatewayPluginConfig({ config, env: { A: "1" } })).toMatchObject({
63+first: true,
64+});
65+expect(resolveGatewayPluginConfig({ config, env: { A: "2" } })).toMatchObject({
66+second: true,
67+});
68+69+expect(mocks.applyPluginAutoEnable).toHaveBeenCalledTimes(2);
70+});
71+72+it("does not cache without a current metadata snapshot", async () => {
73+const { resolveGatewayPluginConfig } = await import("./runtime-plugin-config.js");
74+const config = {} as OpenClawConfig;
75+mocks.getCurrentPluginMetadataSnapshot.mockReturnValue(undefined);
76+mocks.applyPluginAutoEnable.mockImplementation(() => ({ config: {}, changes: [] }));
77+78+resolveGatewayPluginConfig({ config });
79+resolveGatewayPluginConfig({ config });
80+81+expect(mocks.applyPluginAutoEnable).toHaveBeenCalledTimes(2);
82+});
83+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。