import { app , BrowserWindow , shell , Menu , MenuItemConstructorOptions , } from 'electron' ; import signalingServer from './server' ; import MenuBuilder from './menu' ; jest . useFakeTimers ( ) ; jest . mock ( 'electron' , ( ) => { return { app : { quit : jest . fn ( ) , } , shell : { openExternal : jest . fn ( ) , } , Menu : { buildFromTemplate : jest . fn ( ) . mockReturnValue ( { popup : jest . fn ( ) , } ) , setApplicationMenu : jest . fn ( ) , } , } ; } ) ; jest . mock ( './server' , ( ) => { return { stop : jest . fn ( ) , } ; } ) ; describe ( 'app menu MenyBuilder tests' , ( ) => { let menuBuilder ; let testMainWindow ; let testI18n ; beforeEach ( ( ) => { jest . clearAllMocks ( ) ; jest . restoreAllMocks ( ) ; testMainWindow = ( { webContents : { on : jest . fn ( ) , inspectElement : jest . fn ( ) , reload : jest . fn ( ) , toggleDevTools : jest . fn ( ) , } , setFullScreen : jest . fn ( ) , isFullScreen : jest . fn ( ) , inspectElement : jest . fn ( ) , } as unknown ) as BrowserWindow ; testI18n = { t : jest . fn ( ) , language : 'en' , changeLanguage : jest . fn ( ) , } ; menuBuilder = new MenuBuilder ( testMainWindow , testI18n ) ; } ) ; describe ( 'when MenyBuilder created properly' , ( ) => { describe ( 'when setupDevelopmentEnvironment was called' , ( ) => { it ( 'should call .mainWindow.webContents.on("context-menu"' , ( ) => { menuBuilder . setupDevelopmentEnvironment ( ) ; expect ( testMainWindow . webContents . on ) . toBeCalledWith ( 'context-menu' , expect . anything ( ) ) ; } ) ; describe ( 'when .mainWindow.webContents.on("context-menu" event callback triggered (eg. righti click on any UI element in main host app window)' , ( ) => { it ( 'should build menu with Inspect element on right click with proper coordinates' , ( ) => { const testProps = { x : 123 , y : 321 } ; menuBuilder . setupDevelopmentEnvironment ( ) ; const callback = testMainWindow . webContents . on . mock . calls [ 0 ] [ 1 ] ; callback ( undefined , testProps ) ; expect ( Menu . buildFromTemplate ) . toBeCalledWith ( [ { label : 'Inspect element' , click : expect . anything ( ) , } , ] ) ; const inspectElementCallback = Menu . buildFromTemplate . mock . calls [ 0 ] [ 0 ] [ 0 ] . click ; inspectElementCallback ( ) ; expect ( testMainWindow . webContents . inspectElement ) . toBeCalledWith ( testProps . x , testProps . y ) ; } ) ; } ) ; } ) ; describe ( 'when buildMenu was called' , ( ) => { describe ( 'when buildMenu was called in dev environment' , ( ) => { it ( 'should call setupDevelopmentEnvironment' , ( ) => { const setupDevelopmentEnvironmentBackup = menuBuilder . setupDevelopmentEnvironment ; menuBuilder . setupDevelopmentEnvironment = jest . fn ( ) ; const backupNodeEnv = process . env . NODE_ENV ; const backupEnvDebugProd = process . env . DEBUG_PROD ; process . env . NODE_ENV = 'development' ; menuBuilder . buildMenu ( ) ; expect ( menuBuilder . setupDevelopmentEnvironment ) . toBeCalled ( ) ; process . env . NODE_ENV = backupNodeEnv ; menuBuilder . setupDevelopmentEnvironment . mockClear ( ) ; process . env . DEBUG_PROD = 'true' ; menuBuilder . buildMenu ( ) ; expect ( menuBuilder . setupDevelopmentEnvironment ) . toBeCalled ( ) ; process . env . NODE_ENV = backupNodeEnv ; process . env . DEBUG_PROD = backupEnvDebugProd ; menuBuilder . setupDevelopmentEnvironment = setupDevelopmentEnvironmentBackup ; } ) ; } ) ; describe ( 'when buildMenu was called when process.platform === "darwin"' , ( ) => { it ( 'should call buildDarwinTemplate and setApplicationMenu with built template' , ( ) => { const buildDarwinTemplateBackup = menuBuilder . buildDarwinTemplate ; const testReturnMenu = [ ] as MenuItemConstructorOptions [ ] ; menuBuilder . buildDarwinTemplate = jest . fn ( ) . mockReturnValueOnce ( testReturnMenu ) ; const testMenuMock = { asdf : 'asdf' } ; Menu . buildFromTemplate . mockReturnValueOnce ( testMenuMock ) ; const processBackup = process ; process = { ... processBackup , platform : 'darwin' , } ; menuBuilder . buildMenu ( ) ; expect ( Menu . buildFromTemplate ) . toBeCalledWith ( testReturnMenu ) ; expect ( menuBuilder . buildDarwinTemplate ) . toBeCalled ( ) ; expect ( Menu . setApplicationMenu ) . toBeCalledWith ( testMenuMock ) ; process = processBackup ; menuBuilder . buildDarwinTemplate = buildDarwinTemplateBackup ; } ) ; } ) ; describe ( 'when buildMenu was called when process.platform !== "darwin"' , ( ) => { it ( 'should call setApplicationMenu with null' , ( ) => { const processBackup = process ; process = { ... processBackup , platform : 'linux' , } ; menuBuilder . buildMenu ( ) ; expect ( Menu . setApplicationMenu ) . toBeCalledWith ( null ) ; process = processBackup ; } ) ; } ) ; } ) ; describe ( 'when menu from buildDarwinTemplate was created' , ( ) => { it ( 'should match a snapshot' , ( ) => { expect ( menuBuilder . buildDarwinTemplate ( ) ) . toMatchSnapshot ( ) ; } ) ; describe ( 'when in About submenu menu quit label click event occured' , ( ) => { it ( 'should call app.quit() and stop() on signaling server, stop should be called before quit' , ( ) => { const res = menuBuilder . buildDarwinTemplate ( ) ; const submenuAbout = res [ 0 ] ; const quitLabel = submenuAbout . submenu [ submenuAbout . submenu . length - 1 ] ; quitLabel . click ( ) ; expect ( signalingServer . stop ) . toHaveBeenCalled ( ) ; expect ( app . quit ) . toHaveBeenCalled ( ) ; } ) ; } ) ; describe ( 'when menu was built in debug or dev environment' , ( ) => { describe ( 'when in View submenu, Reload menu label was clicked' , ( ) => { it ( 'should call .mainWindow.webContents.reload() on main window' , ( ) => { const prevNodeEnv = process . env . NODE_ENV ; const prevEnvDebugProd = process . env . DEBUG_PROD ; process . env . NODE_ENV = 'development' ; const menu1 = menuBuilder . buildDarwinTemplate ( ) ; const submenuView1 = menu1 [ 2 ] ; const reloadLabel = submenuView1 . submenu [ 0 ] ; reloadLabel . click ( ) ; expect ( testMainWindow . webContents . reload ) . toBeCalled ( ) ; testMainWindow . webContents . reload . mockClear ( ) ; process . env . NODE_ENV = prevNodeEnv ; process . env . DEBUG_PROD = 'true' ; const menu2 = menuBuilder . buildDarwinTemplate ( ) ; const submenuView2 = menu2 [ 2 ] ; const toggleDevTools = submenuView2 . submenu [ 2 ] ; toggleDevTools . click ( ) ; expect ( testMainWindow . webContents . toggleDevTools ) . toBeCalled ( ) ; testMainWindow . webContents . toggleDevTools . mockClear ( ) ; const menu3 = menuBuilder . buildDarwinTemplate ( ) ; const submenuView3 = menu3 [ 2 ] ; const toggleFullScreen = submenuView3 . submenu [ 1 ] ; toggleFullScreen . click ( ) ; expect ( testMainWindow . setFullScreen ) . toBeCalled ( ) ; expect ( testMainWindow . isFullScreen ) . toBeCalled ( ) ; testMainWindow . webContents . toggleDevTools . mockClear ( ) ; process . env . NODE_ENV = prevNodeEnv ; process . env . DEBUG_PROD = prevEnvDebugProd ; } ) ; } ) ; } ) ; describe ( 'when menu was built in production environment' , ( ) => { describe ( 'when toggle fullscreen was clicked' , ( ) => { it ( 'should call setFullsScreen and isFullScreen on main window' , ( ) => { const menu = menuBuilder . buildDarwinTemplate ( ) ; const submenuView = menu [ 2 ] ; const toggleFullScreen = submenuView . submenu [ 0 ] ; toggleFullScreen . click ( ) ; expect ( testMainWindow . setFullScreen ) . toBeCalled ( ) ; expect ( testMainWindow . isFullScreen ) . toBeCalled ( ) ; } ) ; } ) ; } ) ; describe ( 'when Help submenu Lean More was clicked' , ( ) => { it ( 'shoud call shell open external with proper link to https://www.deskreen.com/' , ( ) => { const menu = menuBuilder . buildDarwinTemplate ( ) ; const submenuView = menu [ 4 ] ; const learnMore = submenuView . submenu [ 0 ] ; learnMore . click ( ) ; expect ( shell . openExternal ) . toBeCalledWith ( 'https://www.deskreen.com/' ) ; } ) ; } ) ; describe ( 'when Help submenu Documentation was clicked' , ( ) => { it ( 'shoud call shell open external with proper link to https://github.com/pavlobu/deskreen/blob/master/README.md' , ( ) => { const menu = menuBuilder . buildDarwinTemplate ( ) ; const submenuView = menu [ 4 ] ; const learnMore = submenuView . submenu [ 1 ] ; learnMore . click ( ) ; expect ( shell . openExternal ) . toBeCalledWith ( 'https://github.com/pavlobu/deskreen/blob/master/README.md' ) ; } ) ; } ) ; describe ( 'when Help submenu Community Discussions was clicked' , ( ) => { it ( 'shoud call shell open external with proper link to https://github.com/pavlobu/deskreen/discussions' , ( ) => { const menu = menuBuilder . buildDarwinTemplate ( ) ; const submenuView = menu [ 4 ] ; const learnMore = submenuView . submenu [ 2 ] ; learnMore . click ( ) ; expect ( shell . openExternal ) . toBeCalledWith ( 'https://github.com/pavlobu/deskreen/discussions' ) ; } ) ; } ) ; describe ( 'when Help submenu Search Issues was clicked' , ( ) => { it ( 'shoud call shell open external with proper link to https://github.com/pavlobu/deskreen/issues' , ( ) => { const menu = menuBuilder . buildDarwinTemplate ( ) ; const submenuView = menu [ 4 ] ; const learnMore = submenuView . submenu [ 3 ] ; learnMore . click ( ) ; expect ( shell . openExternal ) . toBeCalledWith ( 'https://github.com/pavlobu/deskreen/issues' ) ; } ) ; } ) ; } ) ; } ) ; } ) ;