




















@@ -1,12 +1,18 @@
11import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
223-const applyPluginDoctorCompatibilityMigrations = vi.hoisted(() => vi.fn());
3+const { applyPluginDoctorCompatibilityMigrations, collectRelevantDoctorPluginIds } = vi.hoisted(
4+() => ({
5+applyPluginDoctorCompatibilityMigrations: vi.fn(),
6+collectRelevantDoctorPluginIds: vi.fn(),
7+}),
8+);
49const loadBundledChannelDoctorContractApi = vi.hoisted(() => vi.fn());
510const getBootstrapChannelPlugin = vi.hoisted(() => vi.fn());
611712vi.mock("../../../plugins/doctor-contract-registry.js", () => ({
813applyPluginDoctorCompatibilityMigrations: (...args: unknown[]) =>
914applyPluginDoctorCompatibilityMigrations(...args),
15+collectRelevantDoctorPluginIds: (...args: unknown[]) => collectRelevantDoctorPluginIds(...args),
1016}));
11171218vi.mock("../../../channels/plugins/doctor-contract-api.js", () => ({
@@ -30,12 +36,14 @@ beforeAll(async () => {
30363137beforeEach(() => {
3238applyPluginDoctorCompatibilityMigrations.mockReset();
39+collectRelevantDoctorPluginIds.mockReset();
3340loadBundledChannelDoctorContractApi.mockReset();
3441getBootstrapChannelPlugin.mockReset();
3542});
36433744describe("bundled channel legacy config migrations", () => {
3845it("prefers bundled channel doctor contract normalizers before plugin registry fallback", () => {
46+collectRelevantDoctorPluginIds.mockReturnValueOnce([]);
3947loadBundledChannelDoctorContractApi.mockImplementation((channelId: string) =>
4048channelId === "slack"
4149 ? {
@@ -82,6 +90,7 @@ describe("bundled channel legacy config migrations", () => {
8290});
83918492it("normalizes legacy private-network aliases exposed through bundled contract surfaces", () => {
93+collectRelevantDoctorPluginIds.mockReturnValueOnce(["mattermost"]);
8594loadBundledChannelDoctorContractApi.mockReturnValue(undefined);
8695getBootstrapChannelPlugin.mockReturnValue(undefined);
8796applyPluginDoctorCompatibilityMigrations.mockReturnValueOnce({
@@ -121,6 +130,7 @@ describe("bundled channel legacy config migrations", () => {
121130});
122131123132expect(applyPluginDoctorCompatibilityMigrations).toHaveBeenCalledWith(expect.any(Object), {
133+config: expect.any(Object),
124134pluginIds: ["mattermost"],
125135});
126136@@ -147,4 +157,42 @@ describe("bundled channel legacy config migrations", () => {
147157]),
148158);
149159});
160+161+it("applies plugin doctor normalizers for configured non-channel plugin entries", () => {
162+collectRelevantDoctorPluginIds.mockReturnValueOnce(["lossless-claw"]);
163+applyPluginDoctorCompatibilityMigrations.mockReturnValueOnce({
164+config: {
165+plugins: {
166+entries: {
167+"lossless-claw": {
168+llm: {
169+allowModelOverride: true,
170+allowedModels: ["openai-codex/gpt-5.4-mini"],
171+},
172+},
173+},
174+},
175+},
176+changes: ["Configured plugins.entries.lossless-claw.llm.allowedModels."],
177+});
178+179+const config = {
180+plugins: {
181+entries: {
182+"lossless-claw": {
183+config: {
184+summaryModel: "openai-codex/gpt-5.4-mini",
185+},
186+},
187+},
188+},
189+};
190+const result = applyChannelDoctorCompatibilityMigrations(config);
191+192+expect(applyPluginDoctorCompatibilityMigrations).toHaveBeenCalledWith(expect.any(Object), {
193+ config,
194+pluginIds: ["lossless-claw"],
195+});
196+expect(result.changes).toEqual(["Configured plugins.entries.lossless-claw.llm.allowedModels."]);
197+});
150198});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。