diff --git a/src/extension/main.ts b/src/extension/main.ts index 266f0956..46fd486c 100644 --- a/src/extension/main.ts +++ b/src/extension/main.ts @@ -20,7 +20,8 @@ export const registerCommands = ( quickPickCreator: ReturnType, terminalManager: TerminalManager, statusBarManager: StatusBarManager, - treeProvider: CommandTreeProvider + treeProvider: CommandTreeProvider, + configManager: ConfigManager ) => { const executeCommand = vscode.commands.registerCommand( "quickCommandButtons.execute", @@ -52,19 +53,19 @@ export const registerCommands = ( const openConfigCommand = vscode.commands.registerCommand( "quickCommandButtons.openConfig", - ConfigWebviewProvider.createWebviewCommand(context.extensionUri, configReader) + ConfigWebviewProvider.createWebviewCommand(context.extensionUri, configReader, configManager) ); const toggleConfigurationTargetCommand = vscode.commands.registerCommand( "quickCommandButtons.toggleConfigurationTarget", async () => { - const currentTarget = ConfigManager.getCurrentConfigurationTarget(); + const currentTarget = configManager.getCurrentConfigurationTarget(); const newTarget = currentTarget === CONFIGURATION_TARGETS.WORKSPACE ? CONFIGURATION_TARGETS.GLOBAL : CONFIGURATION_TARGETS.WORKSPACE; - await ConfigManager.updateConfigurationTarget(newTarget); + await configManager.updateConfigurationTarget(newTarget); } ); @@ -87,6 +88,7 @@ export const activate = (context: vscode.ExtensionContext) => { const terminalManager = TerminalManager.create(); const statusBarManager = StatusBarManager.create(configReader, statusBarCreator); const treeProvider = CommandTreeProvider.create(configReader); + const configManager = ConfigManager.create(); statusBarManager.refreshButtons(); @@ -101,7 +103,8 @@ export const activate = (context: vscode.ExtensionContext) => { quickPickCreator, terminalManager, statusBarManager, - treeProvider + treeProvider, + configManager ); const treeView = vscode.window.createTreeView("quickCommandsTree", { diff --git a/src/internal/managers/config-manager.ts b/src/internal/managers/config-manager.ts index b5be9001..0fd0f6b6 100644 --- a/src/internal/managers/config-manager.ts +++ b/src/internal/managers/config-manager.ts @@ -8,8 +8,16 @@ import { } from "../../pkg/config-constants"; import { ButtonConfig } from "../../pkg/types"; +type ConfigReader = { getButtons(): ButtonConfig[] }; + export class ConfigManager { - static getConfigDataForWebview(configReader: { getButtons(): ButtonConfig[] }): { + private constructor() {} + + static create(): ConfigManager { + return new ConfigManager(); + } + + getConfigDataForWebview(configReader: ConfigReader): { buttons: ButtonConfig[]; configurationTarget: ConfigurationTargetType; } { @@ -19,7 +27,7 @@ export class ConfigManager { }; } - static getCurrentConfigurationTarget(): ConfigurationTargetType { + getCurrentConfigurationTarget(): ConfigurationTargetType { const config = vscode.workspace.getConfiguration(CONFIG_SECTION); return config.get( CONFIG_KEYS.CONFIGURATION_TARGET, @@ -27,49 +35,24 @@ export class ConfigManager { ); } - static getVSCodeConfigurationTarget(): vscode.ConfigurationTarget { + getVSCodeConfigurationTarget(): vscode.ConfigurationTarget { const currentTarget = this.getCurrentConfigurationTarget(); return VS_CODE_CONFIGURATION_TARGETS[currentTarget]; } - static async updateButtonConfiguration(buttons: ButtonConfig[]): Promise { - try { - const config = vscode.workspace.getConfiguration(CONFIG_SECTION); - const target = this.getVSCodeConfigurationTarget(); - - await config.update(CONFIG_KEYS.BUTTONS, buttons, target); - - const currentTarget = this.getCurrentConfigurationTarget(); - const targetMessage = - currentTarget === CONFIGURATION_TARGETS.GLOBAL ? "user settings" : "workspace settings"; + async updateButtonConfiguration(buttons: ButtonConfig[]): Promise { + const config = vscode.workspace.getConfiguration(CONFIG_SECTION); + const target = this.getVSCodeConfigurationTarget(); - vscode.window.showInformationMessage( - `Configuration updated successfully in ${targetMessage}!` - ); - } catch (error) { - console.error("Failed to update configuration:", error); - vscode.window.showErrorMessage("Failed to update configuration. Please try again."); - } + await config.update(CONFIG_KEYS.BUTTONS, buttons, target); } - static async updateConfigurationTarget(target: ConfigurationTargetType): Promise { - try { - const config = vscode.workspace.getConfiguration(CONFIG_SECTION); - await config.update( - CONFIG_KEYS.CONFIGURATION_TARGET, - target, - vscode.ConfigurationTarget.Global // Configuration target setting itself should always be global - ); - - const targetMessage = - target === CONFIGURATION_TARGETS.GLOBAL - ? "user settings (shared across all projects)" - : "workspace settings (project-specific)"; - - vscode.window.showInformationMessage(`Configuration target changed to: ${targetMessage}`); - } catch (error) { - console.error("Failed to update configuration target:", error); - vscode.window.showErrorMessage("Failed to update configuration target. Please try again."); - } + async updateConfigurationTarget(target: ConfigurationTargetType): Promise { + const config = vscode.workspace.getConfiguration(CONFIG_SECTION); + await config.update( + CONFIG_KEYS.CONFIGURATION_TARGET, + target, + vscode.ConfigurationTarget.Global // Configuration target setting itself should always be global + ); } } diff --git a/src/internal/managers/status-bar-manager.ts b/src/internal/managers/status-bar-manager.ts index 56a1c1e6..dd84c52e 100644 --- a/src/internal/managers/status-bar-manager.ts +++ b/src/internal/managers/status-bar-manager.ts @@ -16,7 +16,16 @@ export const createButtonCommand = (button: ButtonConfig) => ({ title: "Execute Command", }); -export const configureRefreshButton = (button: vscode.StatusBarItem, refreshConfig: any) => { +type RefreshConfig = { + color: string; + enabled: boolean; + icon: string; +}; + +export const configureRefreshButton = ( + button: vscode.StatusBarItem, + refreshConfig: RefreshConfig +) => { button.text = refreshConfig.icon; button.tooltip = "Refresh Quick Command Buttons"; button.command = "quickCommandButtons.refresh"; diff --git a/src/internal/providers/webview-provider.ts b/src/internal/providers/webview-provider.ts index 6c2fac69..31742f26 100644 --- a/src/internal/providers/webview-provider.ts +++ b/src/internal/providers/webview-provider.ts @@ -2,7 +2,7 @@ import * as fs from "fs"; import * as path from "path"; import * as vscode from "vscode"; import { ConfigurationTargetType } from "../../pkg/config-constants"; -import { ButtonConfig } from "../../pkg/types"; +import { ButtonConfig, WebviewMessage } from "../../pkg/types"; import { ConfigReader } from "../adapters"; import { ConfigManager } from "../managers/config-manager"; @@ -67,27 +67,28 @@ export const buildWebviewHtml = (extensionUri: vscode.Uri, webview: vscode.Webvi return html; }; -export const updateButtonConfiguration = async (buttons: ButtonConfig[]): Promise => { - await ConfigManager.updateButtonConfiguration(buttons); -}; - const handleWebviewMessage = async ( - data: any, + message: WebviewMessage, webview: vscode.Webview, - configReader: ConfigReader + configReader: ConfigReader, + configManager: ConfigManager ): Promise => { - switch (data.type) { + switch (message.type) { case "getConfig": webview.postMessage({ - data: ConfigManager.getConfigDataForWebview(configReader), + data: configManager.getConfigDataForWebview(configReader), type: "configData", }); break; case "setConfig": - await updateButtonConfiguration(data.data); + if (Array.isArray(message.data)) { + await configManager.updateButtonConfiguration(message.data as ButtonConfig[]); + } break; case "setConfigurationTarget": - await ConfigManager.updateConfigurationTarget(data.target as ConfigurationTargetType); + if (message.target) { + await configManager.updateConfigurationTarget(message.target as ConfigurationTargetType); + } break; } }; @@ -98,10 +99,15 @@ export class ConfigWebviewProvider implements vscode.WebviewViewProvider { constructor( private readonly _extensionUri: vscode.Uri, - private configReader: ConfigReader + private configReader: ConfigReader, + private configManager: ConfigManager ) {} - public static createWebviewCommand(extensionUri: vscode.Uri, configReader: ConfigReader) { + public static createWebviewCommand( + extensionUri: vscode.Uri, + configReader: ConfigReader, + configManager: ConfigManager + ) { return () => { const panel = vscode.window.createWebviewPanel( "quickCommandsConfig", @@ -115,13 +121,13 @@ export class ConfigWebviewProvider implements vscode.WebviewViewProvider { panel.webview.html = buildWebviewHtml(extensionUri, panel.webview); - panel.webview.onDidReceiveMessage(async (data) => { - await handleWebviewMessage(data, panel.webview, configReader); + panel.webview.onDidReceiveMessage(async (data: WebviewMessage) => { + await handleWebviewMessage(data, panel.webview, configReader, configManager); }, undefined); // Send initial config panel.webview.postMessage({ - data: ConfigManager.getConfigDataForWebview(configReader), + data: configManager.getConfigDataForWebview(configReader), type: "configData", }); }; @@ -141,8 +147,8 @@ export class ConfigWebviewProvider implements vscode.WebviewViewProvider { webviewView.webview.html = this._getHtmlForWebview(webviewView.webview); - webviewView.webview.onDidReceiveMessage(async (data) => { - await handleWebviewMessage(data, webviewView.webview, this.configReader); + webviewView.webview.onDidReceiveMessage(async (data: WebviewMessage) => { + await handleWebviewMessage(data, webviewView.webview, this.configReader, this.configManager); }, undefined); } diff --git a/src/tests/config-manager.spec.ts b/src/tests/config-manager.spec.ts new file mode 100644 index 00000000..057aaa14 --- /dev/null +++ b/src/tests/config-manager.spec.ts @@ -0,0 +1,201 @@ +import * as vscode from "vscode"; +import { ConfigManager } from "../internal/managers/config-manager"; +import { CONFIGURATION_TARGETS } from "../pkg/config-constants"; + +describe("ConfigManager", () => { + const createMockConfig = () => ({ + get: jest.fn(), + update: jest.fn(), + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + describe("create", () => { + it("should create ConfigManager instance", () => { + const configManager = ConfigManager.create(); + expect(configManager).toBeInstanceOf(ConfigManager); + }); + }); + + describe("getCurrentConfigurationTarget", () => { + it("should return workspace target by default", () => { + const mockConfig = createMockConfig(); + mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE); + jest + .spyOn(vscode.workspace, "getConfiguration") + .mockReturnValue(mockConfig as unknown as vscode.WorkspaceConfiguration); + + const configManager = ConfigManager.create(); + const result = configManager.getCurrentConfigurationTarget(); + + expect(result).toBe(CONFIGURATION_TARGETS.WORKSPACE); + expect(mockConfig.get).toHaveBeenCalledWith( + "configurationTarget", + CONFIGURATION_TARGETS.WORKSPACE + ); + }); + + it("should return global target when configured", () => { + const mockConfig = createMockConfig(); + mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.GLOBAL); + jest + .spyOn(vscode.workspace, "getConfiguration") + .mockReturnValue(mockConfig as unknown as vscode.WorkspaceConfiguration); + + const configManager = ConfigManager.create(); + const result = configManager.getCurrentConfigurationTarget(); + + expect(result).toBe(CONFIGURATION_TARGETS.GLOBAL); + }); + }); + + describe("getVSCodeConfigurationTarget", () => { + it("should return vscode.ConfigurationTarget.Workspace for workspace target", () => { + const mockConfig = createMockConfig(); + mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE); + jest + .spyOn(vscode.workspace, "getConfiguration") + .mockReturnValue(mockConfig as unknown as vscode.WorkspaceConfiguration); + + const configManager = ConfigManager.create(); + const result = configManager.getVSCodeConfigurationTarget(); + + expect(result).toBe(vscode.ConfigurationTarget.Workspace); + }); + + it("should return vscode.ConfigurationTarget.Global for global target", () => { + const mockConfig = createMockConfig(); + mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.GLOBAL); + jest + .spyOn(vscode.workspace, "getConfiguration") + .mockReturnValue(mockConfig as unknown as vscode.WorkspaceConfiguration); + + const configManager = ConfigManager.create(); + const result = configManager.getVSCodeConfigurationTarget(); + + expect(result).toBe(vscode.ConfigurationTarget.Global); + }); + }); + + describe("getConfigDataForWebview", () => { + it("should return buttons and configuration target", () => { + const mockButtons = [ + { name: "Test 1", command: "echo test1" }, + { name: "Test 2", command: "echo test2" }, + ]; + const mockConfigReader = { + getButtons: jest.fn().mockReturnValue(mockButtons), + }; + const mockConfig = createMockConfig(); + mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE); + jest + .spyOn(vscode.workspace, "getConfiguration") + .mockReturnValue(mockConfig as unknown as vscode.WorkspaceConfiguration); + + const configManager = ConfigManager.create(); + const result = configManager.getConfigDataForWebview(mockConfigReader); + + expect(result).toEqual({ + buttons: mockButtons, + configurationTarget: CONFIGURATION_TARGETS.WORKSPACE, + }); + expect(mockConfigReader.getButtons).toHaveBeenCalled(); + }); + }); + + describe("updateButtonConfiguration", () => { + it("should update buttons configuration with correct target", async () => { + const mockButtons = [{ name: "Test", command: "echo test" }]; + const mockConfig = createMockConfig(); + mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.WORKSPACE); + mockConfig.update.mockResolvedValue(undefined); + jest + .spyOn(vscode.workspace, "getConfiguration") + .mockReturnValue(mockConfig as unknown as vscode.WorkspaceConfiguration); + + const configManager = ConfigManager.create(); + await configManager.updateButtonConfiguration(mockButtons); + + expect(mockConfig.update).toHaveBeenCalledWith( + "buttons", + mockButtons, + vscode.ConfigurationTarget.Workspace + ); + }); + + it("should use global target when configured", async () => { + const mockButtons = [{ name: "Test", command: "echo test" }]; + const mockConfig = createMockConfig(); + mockConfig.get.mockReturnValue(CONFIGURATION_TARGETS.GLOBAL); + mockConfig.update.mockResolvedValue(undefined); + jest + .spyOn(vscode.workspace, "getConfiguration") + .mockReturnValue(mockConfig as unknown as vscode.WorkspaceConfiguration); + + const configManager = ConfigManager.create(); + await configManager.updateButtonConfiguration(mockButtons); + + expect(mockConfig.update).toHaveBeenCalledWith( + "buttons", + mockButtons, + vscode.ConfigurationTarget.Global + ); + }); + }); + + describe("updateConfigurationTarget", () => { + it("should update configuration target to global", async () => { + const mockConfig = createMockConfig(); + mockConfig.update.mockResolvedValue(undefined); + jest + .spyOn(vscode.workspace, "getConfiguration") + .mockReturnValue(mockConfig as unknown as vscode.WorkspaceConfiguration); + + const configManager = ConfigManager.create(); + await configManager.updateConfigurationTarget(CONFIGURATION_TARGETS.GLOBAL); + + expect(mockConfig.update).toHaveBeenCalledWith( + "configurationTarget", + CONFIGURATION_TARGETS.GLOBAL, + vscode.ConfigurationTarget.Global + ); + }); + + it("should update configuration target to workspace", async () => { + const mockConfig = createMockConfig(); + mockConfig.update.mockResolvedValue(undefined); + jest + .spyOn(vscode.workspace, "getConfiguration") + .mockReturnValue(mockConfig as unknown as vscode.WorkspaceConfiguration); + + const configManager = ConfigManager.create(); + await configManager.updateConfigurationTarget(CONFIGURATION_TARGETS.WORKSPACE); + + expect(mockConfig.update).toHaveBeenCalledWith( + "configurationTarget", + CONFIGURATION_TARGETS.WORKSPACE, + vscode.ConfigurationTarget.Global + ); + }); + + it("should always use Global target for configurationTarget setting", async () => { + const mockConfig = createMockConfig(); + mockConfig.update.mockResolvedValue(undefined); + jest + .spyOn(vscode.workspace, "getConfiguration") + .mockReturnValue(mockConfig as unknown as vscode.WorkspaceConfiguration); + + const configManager = ConfigManager.create(); + await configManager.updateConfigurationTarget(CONFIGURATION_TARGETS.WORKSPACE); + + const updateCall = mockConfig.update.mock.calls[0]; + expect(updateCall[2]).toBe(vscode.ConfigurationTarget.Global); + }); + }); +}); diff --git a/src/tests/main.spec.ts b/src/tests/main.spec.ts index 93915ec0..7ec97484 100644 --- a/src/tests/main.spec.ts +++ b/src/tests/main.spec.ts @@ -1,5 +1,6 @@ import * as vscode from "vscode"; import { registerCommands } from "../extension/main"; +import { ConfigManager } from "../internal/managers/config-manager"; import { StatusBarManager } from "../internal/managers/status-bar-manager"; import { TerminalManager } from "../internal/managers/terminal-manager"; import { CommandTreeProvider } from "../internal/providers/command-tree-provider"; @@ -34,6 +35,7 @@ describe("main", () => { let mockTerminalManager: TerminalManager; let mockStatusBarManager: StatusBarManager; let mockTreeProvider: CommandTreeProvider; + let mockConfigManager: ConfigManager; beforeEach(() => { jest.clearAllMocks(); @@ -61,6 +63,11 @@ describe("main", () => { refresh: jest.fn(), } as any; + mockConfigManager = { + getCurrentConfigurationTarget: jest.fn(), + updateConfigurationTarget: jest.fn(), + } as any; + (vscode.commands.registerCommand as jest.Mock).mockReturnValue("mockDisposable"); }); @@ -72,7 +79,8 @@ describe("main", () => { mockQuickPickCreator, mockTerminalManager, mockStatusBarManager, - mockTreeProvider + mockTreeProvider, + mockConfigManager ); expect(vscode.commands.registerCommand).toHaveBeenCalledWith( @@ -89,7 +97,8 @@ describe("main", () => { mockQuickPickCreator, mockTerminalManager, mockStatusBarManager, - mockTreeProvider + mockTreeProvider, + mockConfigManager ); expect(vscode.commands.registerCommand).toHaveBeenCalledWith( @@ -106,7 +115,8 @@ describe("main", () => { mockQuickPickCreator, mockTerminalManager, mockStatusBarManager, - mockTreeProvider + mockTreeProvider, + mockConfigManager ); expect(vscode.commands.registerCommand).toHaveBeenCalledWith( @@ -123,7 +133,8 @@ describe("main", () => { mockQuickPickCreator, mockTerminalManager, mockStatusBarManager, - mockTreeProvider + mockTreeProvider, + mockConfigManager ); expect(vscode.commands.registerCommand).toHaveBeenCalledWith( @@ -143,7 +154,8 @@ describe("main", () => { mockQuickPickCreator, mockTerminalManager, mockStatusBarManager, - mockTreeProvider + mockTreeProvider, + mockConfigManager ); expect(vscode.commands.registerCommand).toHaveBeenCalledWith( @@ -168,7 +180,8 @@ describe("main", () => { mockQuickPickCreator, mockTerminalManager, mockStatusBarManager, - mockTreeProvider + mockTreeProvider, + mockConfigManager ); expect(vscode.commands.registerCommand).toHaveBeenCalledWith( @@ -177,7 +190,8 @@ describe("main", () => { ); expect(ConfigWebviewProvider.createWebviewCommand).toHaveBeenCalledWith( mockContext.extensionUri, - mockConfigReader + mockConfigReader, + mockConfigManager ); expect(commands.openConfigCommand).toBe("mockDisposable"); }); @@ -189,7 +203,8 @@ describe("main", () => { mockQuickPickCreator, mockTerminalManager, mockStatusBarManager, - mockTreeProvider + mockTreeProvider, + mockConfigManager ); expect(commands).toEqual({ diff --git a/src/tests/status-bar-manager.spec.ts b/src/tests/status-bar-manager.spec.ts index 92e30df1..295a2a6a 100644 --- a/src/tests/status-bar-manager.spec.ts +++ b/src/tests/status-bar-manager.spec.ts @@ -186,6 +186,7 @@ describe("status-bar-manager", () => { it("should configure refresh button with all properties", () => { const refreshConfig = { color: "#00FF00", + enabled: true, icon: "🔄", }; @@ -199,6 +200,8 @@ describe("status-bar-manager", () => { it("should configure refresh button with minimal properties", () => { const refreshConfig = { + color: "", + enabled: true, icon: "⟳", }; @@ -207,12 +210,13 @@ describe("status-bar-manager", () => { expect(mockStatusBarItem.text).toBe("⟳"); expect(mockStatusBarItem.tooltip).toBe("Refresh Quick Command Buttons"); expect(mockStatusBarItem.command).toBe("quickCommandButtons.refresh"); - expect(mockStatusBarItem.color).toBeUndefined(); + expect(mockStatusBarItem.color).toBe(""); }); it("should handle refresh config with color set to undefined", () => { const refreshConfig = { - color: undefined, + color: undefined as any, + enabled: true, icon: "↻", }; @@ -227,6 +231,7 @@ describe("status-bar-manager", () => { it("should handle refresh config with empty icon", () => { const refreshConfig = { color: "#FF0000", + enabled: true, icon: "", }; @@ -240,7 +245,8 @@ describe("status-bar-manager", () => { it("should handle refresh config with null color", () => { const refreshConfig = { - color: null, + color: null as any, + enabled: true, icon: "↺", }; @@ -258,6 +264,7 @@ describe("status-bar-manager", () => { const refreshConfig = { color: "#0000FF", + enabled: true, icon: "🔃", }; diff --git a/src/tests/webview-provider.spec.ts b/src/tests/webview-provider.spec.ts index b954b05a..6787f4f2 100644 --- a/src/tests/webview-provider.spec.ts +++ b/src/tests/webview-provider.spec.ts @@ -1,19 +1,14 @@ import * as fs from "fs"; import * as path from "path"; import * as vscode from "vscode"; -import { ConfigManager } from "../internal/managers/config-manager"; import { generateFallbackHtml, replaceAssetPaths, injectSecurityAndVSCodeApi, checkWebviewFilesExist, buildWebviewHtml, - updateButtonConfiguration, } from "../internal/providers/webview-provider"; -// Mock ConfigManager -jest.mock("../internal/managers/config-manager"); - // Mock fs module jest.mock("fs"); @@ -442,98 +437,4 @@ describe("webview-provider", () => { expect(result).not.toContain("vscode-webview://assets-uri/"); }); }); - - describe("updateButtonConfiguration", () => { - beforeEach(() => { - jest.clearAllMocks(); - (ConfigManager.updateButtonConfiguration as jest.Mock).mockResolvedValue(undefined); - }); - - it("should successfully update button configuration", async () => { - const buttons = [ - { command: "echo test", name: "Test Button" }, - { - group: [{ command: "echo sub", name: "Sub Button" }], - name: "Group Button", - }, - ]; - - await updateButtonConfiguration(buttons); - - expect(ConfigManager.updateButtonConfiguration).toHaveBeenCalledWith(buttons); - }); - - it("should delegate configuration update to ConfigManager", async () => { - const buttons = [{ command: "echo test", name: "Test Button" }]; - - await updateButtonConfiguration(buttons); - - expect(ConfigManager.updateButtonConfiguration).toHaveBeenCalledWith(buttons); - }); - - it("should handle empty button array", async () => { - const buttons: any[] = []; - - await updateButtonConfiguration(buttons); - - expect(ConfigManager.updateButtonConfiguration).toHaveBeenCalledWith(buttons); - }); - - it("should handle button configuration with all properties", async () => { - const buttons = [ - { - color: "#FF0000", - command: "echo complex", - executeAll: false, - name: "Complex Button", - shortcut: "c", - terminalName: "custom-terminal", - useVsCodeApi: true, - }, - ]; - - await updateButtonConfiguration(buttons); - - expect(ConfigManager.updateButtonConfiguration).toHaveBeenCalledWith(buttons); - }); - - it("should handle nested group configurations", async () => { - const buttons = [ - { - group: [ - { command: "echo child1", name: "Child 1" }, - { - group: [{ command: "echo deep", name: "Deep Child" }], - name: "Nested Group", - }, - ], - name: "Parent Group", - }, - ]; - - await updateButtonConfiguration(buttons); - - expect(ConfigManager.updateButtonConfiguration).toHaveBeenCalledWith(buttons); - }); - - it("should delegate error handling to ConfigManager", async () => { - const buttons = [{ command: "echo test", name: "Test Button" }]; - - // ConfigManager handles errors internally, so it resolves normally - (ConfigManager.updateButtonConfiguration as jest.Mock).mockResolvedValue(undefined); - - await updateButtonConfiguration(buttons); - expect(ConfigManager.updateButtonConfiguration).toHaveBeenCalledWith(buttons); - }); - - it("should let ConfigManager handle errors internally", async () => { - const buttons = [{ command: "echo test", name: "Test Button" }]; - - // ConfigManager handles errors internally, so it resolves normally - (ConfigManager.updateButtonConfiguration as jest.Mock).mockResolvedValue(undefined); - - await updateButtonConfiguration(buttons); - expect(ConfigManager.updateButtonConfiguration).toHaveBeenCalledWith(buttons); - }); - }); });