
























@@ -1,6 +1,7 @@
11import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
22import type { ChannelPluginCatalogEntry } from "../channels/plugins/catalog.js";
33import type { ChannelPlugin } from "../channels/plugins/types.js";
4+import type { PluginInstallRecord } from "../config/types.plugins.js";
45import { resetPluginRuntimeStateForTest, setActivePluginRegistry } from "../plugins/runtime.js";
56import { DEFAULT_ACCOUNT_ID } from "../routing/session-key.js";
67import { createChannelTestPluginBase, createTestRegistry } from "../test-utils/channel-plugins.js";
@@ -34,6 +35,10 @@ const registryRefreshMocks = vi.hoisted(() => ({
3435refreshPluginRegistryAfterConfigMutation: vi.fn(async () => undefined),
3536}));
363738+const pluginInstallRecordCommitMocks = vi.hoisted(() => ({
39+commitPluginInstallRecordsWithConfig: vi.fn(),
40+}));
41+3742vi.mock("../channels/plugins/catalog.js", () => ({
3843listChannelPluginCatalogEntries: catalogMocks.listChannelPluginCatalogEntries,
3944}));
@@ -56,6 +61,8 @@ vi.mock("./channel-setup/plugin-install.js", () => pluginInstallMocks);
56615762vi.mock("../cli/plugins-registry-refresh.js", () => registryRefreshMocks);
586364+vi.mock("../cli/plugins-install-record-commit.js", () => pluginInstallRecordCommitMocks);
65+5966const runtime = createTestRuntime();
60676168function listConfiguredAccountIds(
@@ -256,6 +263,12 @@ describe("channelsAddCommand", () => {
256263.mockImplementation(async (params: { nextConfig: unknown }) => {
257264await configMocks.writeConfigFile(params.nextConfig);
258265});
266+pluginInstallRecordCommitMocks.commitPluginInstallRecordsWithConfig.mockReset();
267+pluginInstallRecordCommitMocks.commitPluginInstallRecordsWithConfig.mockImplementation(
268+async (params: { nextConfig: unknown }) => {
269+await configMocks.writeConfigFile(params.nextConfig);
270+},
271+);
259272lifecycleMocks.onAccountConfigChanged.mockClear();
260273runtime.log.mockClear();
261274runtime.error.mockClear();
@@ -525,6 +538,60 @@ describe("channelsAddCommand", () => {
525538expectExternalChatEnabledConfigWrite();
526539});
527540541+it("commits channel setup plugin install records with the guarded config write", async () => {
542+configMocks.readConfigFileSnapshot.mockResolvedValue({
543+ ...baseConfigSnapshot,
544+hash: "config-1",
545+});
546+setActivePluginRegistry(createTestRegistry());
547+const catalogEntry = createExternalChatCatalogEntry();
548+catalogMocks.listChannelPluginCatalogEntries.mockReturnValue([catalogEntry]);
549+registerExternalChatSetupPlugin("external-chat");
550+const installRecords: Record<string, PluginInstallRecord> = {
551+"@vendor/external-chat-plugin": {
552+source: "npm",
553+spec: "@vendor/external-chat@1.2.3",
554+},
555+};
556+vi.mocked(ensureChannelSetupPluginInstalled).mockImplementation(async ({ cfg }) => ({
557+cfg: {
558+ ...cfg,
559+plugins: {
560+ ...cfg.plugins,
561+installs: installRecords,
562+},
563+},
564+installed: true,
565+pluginId: "@vendor/external-chat-plugin",
566+status: "installed",
567+}));
568+569+await channelsAddCommand(
570+{
571+channel: "external-chat",
572+account: "default",
573+token: "tenant-scoped",
574+},
575+runtime,
576+{ hasFlags: true },
577+);
578+579+expect(
580+pluginInstallRecordCommitMocks.commitPluginInstallRecordsWithConfig,
581+).toHaveBeenCalledWith({
582+nextInstallRecords: installRecords,
583+nextConfig: expect.not.objectContaining({
584+plugins: expect.objectContaining({ installs: expect.anything() }),
585+}),
586+baseHash: "config-1",
587+});
588+expect(registryRefreshMocks.refreshPluginRegistryAfterConfigMutation).toHaveBeenCalledWith(
589+expect.objectContaining({
590+ installRecords,
591+}),
592+);
593+});
594+528595it("uses the installed plugin id when channel and plugin ids differ", async () => {
529596configMocks.readConfigFileSnapshot.mockResolvedValue({ ...baseConfigSnapshot });
530597setActivePluginRegistry(createTestRegistry());
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。