1+ import { globalShortcut } from 'electron' ;
12import type { Menubar } from 'menubar' ;
23
34import { EVENTS } from '../../shared/events' ;
45
56import { registerSystemHandlers } from './system' ;
67
78const onMock = vi . fn ( ) ;
9+ const handleMock = vi . fn ( ) ;
810
911vi . mock ( 'electron' , ( ) => ( {
1012 ipcMain : {
1113 on : ( ...args : unknown [ ] ) => onMock ( ...args ) ,
14+ handle : ( ...args : unknown [ ] ) => handleMock ( ...args ) ,
1215 } ,
1316 globalShortcut : {
1417 register : vi . fn ( ) ,
@@ -26,6 +29,9 @@ describe('main/handlers/system.ts', () => {
2629 let menubar : Menubar ;
2730
2831 beforeEach ( ( ) => {
32+ vi . clearAllMocks ( ) ;
33+ vi . mocked ( globalShortcut . register ) . mockReturnValue ( true ) ;
34+
2935 menubar = {
3036 showWindow : vi . fn ( ) ,
3137 hideWindow : vi . fn ( ) ,
@@ -35,6 +41,20 @@ describe('main/handlers/system.ts', () => {
3541 } as unknown as Menubar ;
3642 } ) ;
3743
44+ function getKeyboardShortcutHandler ( ) {
45+ registerSystemHandlers ( menubar ) ;
46+ const handleCall = handleMock . mock . calls . find (
47+ ( c ) => c [ 0 ] === EVENTS . UPDATE_KEYBOARD_SHORTCUT ,
48+ ) ;
49+ if ( ! handleCall ) {
50+ throw new Error ( 'UPDATE_KEYBOARD_SHORTCUT handler not registered' ) ;
51+ }
52+ return handleCall [ 1 ] as (
53+ event : Electron . IpcMainInvokeEvent ,
54+ data : { enabled : boolean ; keyboardShortcut : string } ,
55+ ) => { success : boolean } ;
56+ }
57+
3858 describe ( 'registerSystemHandlers' , ( ) => {
3959 it ( 'registers handlers without throwing' , ( ) => {
4060 expect ( ( ) => registerSystemHandlers ( menubar ) ) . not . toThrow ( ) ;
@@ -43,13 +63,105 @@ describe('main/handlers/system.ts', () => {
4363 it ( 'registers expected system IPC event handlers' , ( ) => {
4464 registerSystemHandlers ( menubar ) ;
4565
46- const registeredEvents = onMock . mock . calls . map (
66+ const onEvents = onMock . mock . calls . map ( ( call : [ string ] ) => call [ 0 ] ) ;
67+ const handleEvents = handleMock . mock . calls . map (
4768 ( call : [ string ] ) => call [ 0 ] ,
4869 ) ;
4970
50- expect ( registeredEvents ) . toContain ( EVENTS . OPEN_EXTERNAL ) ;
51- expect ( registeredEvents ) . toContain ( EVENTS . UPDATE_KEYBOARD_SHORTCUT ) ;
52- expect ( registeredEvents ) . toContain ( EVENTS . UPDATE_AUTO_LAUNCH ) ;
71+ expect ( onEvents ) . toContain ( EVENTS . OPEN_EXTERNAL ) ;
72+ expect ( onEvents ) . toContain ( EVENTS . UPDATE_AUTO_LAUNCH ) ;
73+ expect ( handleEvents ) . toContain ( EVENTS . UPDATE_KEYBOARD_SHORTCUT ) ;
74+ } ) ;
75+ } ) ;
76+
77+ describe ( 'UPDATE_KEYBOARD_SHORTCUT' , ( ) => {
78+ it ( 'registers shortcut when enabled' , ( ) => {
79+ const handler = getKeyboardShortcutHandler ( ) ;
80+
81+ const result = handler ( { } as Electron . IpcMainInvokeEvent , {
82+ enabled : true ,
83+ keyboardShortcut : 'CommandOrControl+Shift+G' ,
84+ } ) ;
85+
86+ expect ( result ) . toEqual ( { success : true } ) ;
87+ expect ( globalShortcut . register ) . toHaveBeenCalledWith (
88+ 'CommandOrControl+Shift+G' ,
89+ expect . any ( Function ) ,
90+ ) ;
91+ } ) ;
92+
93+ it ( 'unregisters when disabled after being enabled' , ( ) => {
94+ const handler = getKeyboardShortcutHandler ( ) ;
95+
96+ handler ( { } as Electron . IpcMainInvokeEvent , {
97+ enabled : true ,
98+ keyboardShortcut : 'CommandOrControl+Shift+A' ,
99+ } ) ;
100+ vi . clearAllMocks ( ) ;
101+
102+ const result = handler ( { } as Electron . IpcMainInvokeEvent , {
103+ enabled : false ,
104+ keyboardShortcut : 'CommandOrControl+Shift+A' ,
105+ } ) ;
106+
107+ expect ( result ) . toEqual ( { success : true } ) ;
108+ expect ( globalShortcut . unregister ) . toHaveBeenCalledWith (
109+ 'CommandOrControl+Shift+A' ,
110+ ) ;
111+ expect ( globalShortcut . register ) . not . toHaveBeenCalled ( ) ;
112+ } ) ;
113+
114+ it ( 'unregisters previous shortcut when switching to a new one' , ( ) => {
115+ const handler = getKeyboardShortcutHandler ( ) ;
116+
117+ handler ( { } as Electron . IpcMainInvokeEvent , {
118+ enabled : true ,
119+ keyboardShortcut : 'CommandOrControl+Shift+A' ,
120+ } ) ;
121+ vi . clearAllMocks ( ) ;
122+
123+ handler ( { } as Electron . IpcMainInvokeEvent , {
124+ enabled : true ,
125+ keyboardShortcut : 'CommandOrControl+Shift+B' ,
126+ } ) ;
127+
128+ expect ( globalShortcut . unregister ) . toHaveBeenCalledWith (
129+ 'CommandOrControl+Shift+A' ,
130+ ) ;
131+ expect ( globalShortcut . register ) . toHaveBeenCalledWith (
132+ 'CommandOrControl+Shift+B' ,
133+ expect . any ( Function ) ,
134+ ) ;
135+ } ) ;
136+
137+ it ( 'returns success false and restores previous shortcut when new registration fails' , ( ) => {
138+ const handler = getKeyboardShortcutHandler ( ) ;
139+
140+ handler ( { } as Electron . IpcMainInvokeEvent , {
141+ enabled : true ,
142+ keyboardShortcut : 'CommandOrControl+Shift+A' ,
143+ } ) ;
144+ vi . clearAllMocks ( ) ;
145+ vi . mocked ( globalShortcut . register )
146+ . mockReturnValueOnce ( false )
147+ . mockReturnValue ( true ) ;
148+
149+ const result = handler ( { } as Electron . IpcMainInvokeEvent , {
150+ enabled : true ,
151+ keyboardShortcut : 'CommandOrControl+Shift+B' ,
152+ } ) ;
153+
154+ expect ( result ) . toEqual ( { success : false } ) ;
155+ expect ( globalShortcut . register ) . toHaveBeenNthCalledWith (
156+ 1 ,
157+ 'CommandOrControl+Shift+B' ,
158+ expect . any ( Function ) ,
159+ ) ;
160+ expect ( globalShortcut . register ) . toHaveBeenNthCalledWith (
161+ 2 ,
162+ 'CommandOrControl+Shift+A' ,
163+ expect . any ( Function ) ,
164+ ) ;
53165 } ) ;
54166 } ) ;
55167} ) ;
0 commit comments