import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest" ;
import type { ChannelPluginCatalogEntry } from "../channels/plugins/catalog.js" ;
import { resetPluginRuntimeStateForTest, setActivePluginRegistry } from "../plugins/runtime.js" ;
import { createTestRegistry } from "../test-utils/channel-plugins.js" ;
import {
ensureChannelSetupPluginInstalled,
loadChannelSetupPluginRegistrySnapshotForChannel,
} from "./channel-setup/plugin-install.js" ;
import { configMocks } from "./channels.mock-harness.js" ;
import {
createExternalChatCatalogEntry,
createExternalChatDeletePlugin,
} from "./channels.plugin-install.test-helpers.js" ;
import { baseConfigSnapshot, createTestRuntime } from "./test-runtime-config-helpers.js" ;
let channelsRemoveCommand: typeof import ("./channels.js" ).channelsRemoveCommand;
const catalogMocks = vi.hoisted(() => ({
listChannelPluginCatalogEntries: vi.fn((): ChannelPluginCatalogEntry[] => []),
}));
vi.mock("../channels/plugins/catalog.js" , async () => {
const actual = await vi.importActual<typeof import ("../channels/plugins/catalog.js" )>(
"../channels/plugins/catalog.js" ,
);
return {
...actual,
listChannelPluginCatalogEntries: catalogMocks.listChannelPluginCatalogEntries,
};
});
vi.mock("../channels/plugins/bundled.js" , async () => {
const actual = await vi.importActual<typeof import ("../channels/plugins/bundled.js" )>(
"../channels/plugins/bundled.js" ,
);
return {
...actual,
getBundledChannelPlugin: vi.fn(() => undefined),
};
});
vi.mock("./channel-setup/plugin-install.js" , async () => {
const actual = await vi.importActual<typeof import ("./channel-setup/plugin-install.js" )>(
"./channel-setup/plugin-install.js" ,
);
const { createMockChannelSetupPluginInstallModule } =
await import ("./channels.plugin-install.test-helpers.js" );
return createMockChannelSetupPluginInstallModule(actual);
});
const runtime = createTestRuntime();
describe("channelsRemoveCommand" , () => {
beforeAll(async () => {
({ channelsRemoveCommand } = await import ("./channels.js" ));
});
beforeEach(() => {
resetPluginRuntimeStateForTest();
configMocks.readConfigFileSnapshot.mockClear();
configMocks.writeConfigFile.mockClear();
configMocks.replaceConfigFile
.mockReset()
.mockImplementation(async (params: { nextConfig: unknown }) => {
await configMocks.writeConfigFile(params.nextConfig);
});
runtime.log.mockClear();
runtime.error.mockClear();
runtime.exit.mockClear();
catalogMocks.listChannelPluginCatalogEntries.mockClear();
catalogMocks.listChannelPluginCatalogEntries.mockReturnValue([]);
vi.mocked(ensureChannelSetupPluginInstalled).mockClear();
vi.mocked(ensureChannelSetupPluginInstalled).mockImplementation(async ({ cfg }) => ({
cfg,
installed: true ,
status: "installed" ,
}));
vi.mocked(loadChannelSetupPluginRegistrySnapshotForChannel).mockClear();
vi.mocked(loadChannelSetupPluginRegistrySnapshotForChannel).mockReturnValue(
createTestRegistry(),
);
setActivePluginRegistry(createTestRegistry());
});
it("removes an external channel account after installing its plugin on demand" , async () => {
configMocks.readConfigFileSnapshot.mockResolvedValue({
...baseConfigSnapshot,
config: {
channels: {
"external-chat" : {
enabled: true ,
token: "token-1" ,
},
},
},
});
const catalogEntry: ChannelPluginCatalogEntry = createExternalChatCatalogEntry();
catalogMocks.listChannelPluginCatalogEntries.mockReturnValue([catalogEntry]);
const scopedPlugin = createExternalChatDeletePlugin();
vi.mocked(loadChannelSetupPluginRegistrySnapshotForChannel)
.mockReturnValueOnce(createTestRegistry())
.mockReturnValueOnce(
createTestRegistry([
{
pluginId: "@vendor/external-chat-plugin" ,
plugin: scopedPlugin,
source: "test" ,
},
]),
);
await channelsRemoveCommand(
{
channel: "external-chat" ,
account: "default" ,
delete : true ,
},
runtime,
{ hasFlags: true },
);
expect(ensureChannelSetupPluginInstalled).toHaveBeenCalledWith(
expect.objectContaining({ entry: catalogEntry }),
);
expect(loadChannelSetupPluginRegistrySnapshotForChannel).toHaveBeenCalledTimes(2 );
expect(configMocks.writeConfigFile).toHaveBeenCalledWith(
expect.not.objectContaining({
channels: expect.objectContaining({
"external-chat" : expect.anything(),
}),
}),
);
expect(runtime.error).not.toHaveBeenCalled();
expect(runtime.exit).not.toHaveBeenCalled();
});
});
Messung V0.5 in Prozent C=100 H=100 G=100
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland