1559 lines
53 KiB
JavaScript
1559 lines
53 KiB
JavaScript
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
/* eslint-disable max-lines */
|
|
'use strict';
|
|
|
|
import {app, systemPreferences, desktopCapturer} from 'electron';
|
|
|
|
import Config from 'common/config';
|
|
import {getTabViewName, TAB_MESSAGING} from 'common/tabs/TabView';
|
|
import urlUtils from 'common/utils/url';
|
|
|
|
import {
|
|
getAdjustedWindowBoundaries,
|
|
resetScreensharePermissionsMacOS,
|
|
openScreensharePermissionsSettingsMacOS,
|
|
} from 'main/utils';
|
|
|
|
import {WindowManager} from './windowManager';
|
|
import createMainWindow from './mainWindow';
|
|
import {createSettingsWindow} from './settingsWindow';
|
|
|
|
import CallsWidgetWindow from './callsWidgetWindow';
|
|
|
|
jest.mock('path', () => ({
|
|
resolve: jest.fn(),
|
|
join: jest.fn(),
|
|
}));
|
|
|
|
jest.mock('electron', () => ({
|
|
ipcMain: {
|
|
handle: jest.fn(),
|
|
on: jest.fn(),
|
|
emit: jest.fn(),
|
|
},
|
|
app: {
|
|
getAppPath: jest.fn(),
|
|
quit: jest.fn(),
|
|
dock: {
|
|
show: jest.fn(),
|
|
bounce: jest.fn(),
|
|
},
|
|
},
|
|
systemPreferences: {
|
|
getUserDefault: jest.fn(),
|
|
getMediaAccessStatus: jest.fn(() => 'granted'),
|
|
},
|
|
desktopCapturer: {
|
|
getSources: jest.fn(),
|
|
},
|
|
}));
|
|
|
|
jest.mock('common/config', () => ({}));
|
|
|
|
jest.mock('common/utils/url', () => ({
|
|
isTeamUrl: jest.fn(),
|
|
isAdminUrl: jest.fn(),
|
|
cleanPathName: jest.fn(),
|
|
}));
|
|
jest.mock('common/tabs/TabView', () => ({
|
|
getTabViewName: jest.fn(),
|
|
TAB_MESSAGING: 'tab-messaging',
|
|
}));
|
|
jest.mock('../utils', () => ({
|
|
getAdjustedWindowBoundaries: jest.fn(),
|
|
shouldHaveBackBar: jest.fn(),
|
|
openScreensharePermissionsSettingsMacOS: jest.fn(),
|
|
resetScreensharePermissionsMacOS: jest.fn(),
|
|
}));
|
|
jest.mock('../views/viewManager', () => ({
|
|
ViewManager: jest.fn(),
|
|
LoadingScreenState: {
|
|
HIDDEN: 3,
|
|
},
|
|
}));
|
|
jest.mock('../CriticalErrorHandler', () => jest.fn());
|
|
jest.mock('../views/teamDropdownView', () => jest.fn());
|
|
jest.mock('../views/downloadsDropdownView', () => jest.fn());
|
|
jest.mock('../views/downloadsDropdownMenuView', () => jest.fn());
|
|
jest.mock('./settingsWindow', () => ({
|
|
createSettingsWindow: jest.fn(),
|
|
}));
|
|
jest.mock('./mainWindow', () => jest.fn());
|
|
jest.mock('../downloadsManager', () => ({
|
|
getDownloads: () => {},
|
|
}));
|
|
|
|
jest.mock('./callsWidgetWindow');
|
|
jest.mock('main/views/webContentEvents', () => ({}));
|
|
|
|
describe('main/windows/windowManager', () => {
|
|
describe('handleUpdateConfig', () => {
|
|
const windowManager = new WindowManager();
|
|
|
|
beforeEach(() => {
|
|
windowManager.viewManager = {
|
|
reloadConfiguration: jest.fn(),
|
|
};
|
|
});
|
|
|
|
it('should reload config', () => {
|
|
windowManager.handleUpdateConfig();
|
|
expect(windowManager.viewManager.reloadConfiguration).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('showSettingsWindow', () => {
|
|
const windowManager = new WindowManager();
|
|
windowManager.showMainWindow = jest.fn();
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
delete windowManager.settingsWindow;
|
|
delete windowManager.mainWindow;
|
|
});
|
|
|
|
it('should show settings window if it exists', () => {
|
|
const settingsWindow = {show: jest.fn()};
|
|
windowManager.settingsWindow = settingsWindow;
|
|
windowManager.showSettingsWindow();
|
|
expect(settingsWindow.show).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should create windows if they dont exist and delete the settings window when it is closed', () => {
|
|
let callback;
|
|
createSettingsWindow.mockReturnValue({on: (event, cb) => {
|
|
if (event === 'closed') {
|
|
callback = cb;
|
|
}
|
|
}});
|
|
windowManager.showSettingsWindow();
|
|
expect(windowManager.showMainWindow).toHaveBeenCalled();
|
|
expect(createSettingsWindow).toHaveBeenCalled();
|
|
expect(windowManager.settingsWindow).toBeDefined();
|
|
|
|
callback();
|
|
expect(windowManager.settingsWindow).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('showMainWindow', () => {
|
|
const windowManager = new WindowManager();
|
|
windowManager.viewManager = {
|
|
handleDeepLink: jest.fn(),
|
|
updateMainWindow: jest.fn(),
|
|
};
|
|
windowManager.initializeViewManager = jest.fn();
|
|
|
|
afterEach(() => {
|
|
delete windowManager.mainWindow;
|
|
});
|
|
|
|
it('should show main window if it exists and focus it if it is already visible', () => {
|
|
windowManager.mainWindow = {
|
|
visible: false,
|
|
isVisible: () => windowManager.mainWindow.visible,
|
|
show: jest.fn().mockImplementation(() => {
|
|
windowManager.mainWindow.visible = true;
|
|
}),
|
|
focus: jest.fn(),
|
|
};
|
|
|
|
windowManager.showMainWindow();
|
|
expect(windowManager.mainWindow.show).toHaveBeenCalled();
|
|
|
|
windowManager.showMainWindow();
|
|
expect(windowManager.mainWindow.focus).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should quit the app when the main window fails to create', () => {
|
|
windowManager.showMainWindow();
|
|
expect(app.quit).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should create the main window and add listeners', () => {
|
|
const window = {
|
|
on: jest.fn(),
|
|
once: jest.fn(),
|
|
webContents: {
|
|
setWindowOpenHandler: jest.fn(),
|
|
},
|
|
};
|
|
createMainWindow.mockReturnValue(window);
|
|
windowManager.showMainWindow();
|
|
expect(windowManager.mainWindow).toBe(window);
|
|
expect(window.on).toHaveBeenCalled();
|
|
expect(window.webContents.setWindowOpenHandler).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should open deep link when provided', () => {
|
|
const window = {
|
|
on: jest.fn(),
|
|
once: jest.fn(),
|
|
webContents: {
|
|
setWindowOpenHandler: jest.fn(),
|
|
},
|
|
};
|
|
createMainWindow.mockReturnValue(window);
|
|
windowManager.showMainWindow('mattermost://server-1.com/subpath');
|
|
expect(windowManager.viewManager.handleDeepLink).toHaveBeenCalledWith('mattermost://server-1.com/subpath');
|
|
});
|
|
});
|
|
|
|
describe('handleResizeMainWindow', () => {
|
|
const windowManager = new WindowManager();
|
|
const view = {
|
|
setBounds: jest.fn(),
|
|
tab: {
|
|
url: 'http://server-1.com',
|
|
},
|
|
view: {
|
|
webContents: {
|
|
getURL: jest.fn(),
|
|
},
|
|
},
|
|
};
|
|
windowManager.viewManager = {
|
|
getCurrentView: () => view,
|
|
setLoadingScreenBounds: jest.fn(),
|
|
};
|
|
windowManager.mainWindow = {
|
|
getContentBounds: () => ({width: 800, height: 600}),
|
|
getSize: () => [1000, 900],
|
|
};
|
|
windowManager.teamDropdown = {
|
|
updateWindowBounds: jest.fn(),
|
|
};
|
|
|
|
beforeEach(() => {
|
|
jest.useFakeTimers();
|
|
getAdjustedWindowBoundaries.mockImplementation((width, height) => ({width, height}));
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.runAllTimers();
|
|
jest.resetAllMocks();
|
|
jest.runOnlyPendingTimers();
|
|
jest.clearAllTimers();
|
|
jest.useRealTimers();
|
|
});
|
|
|
|
it('should update loading screen and team dropdown bounds', () => {
|
|
windowManager.handleResizeMainWindow();
|
|
expect(windowManager.viewManager.setLoadingScreenBounds).toHaveBeenCalled();
|
|
expect(windowManager.teamDropdown.updateWindowBounds).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should use getSize when the platform is linux', () => {
|
|
const originalPlatform = process.platform;
|
|
Object.defineProperty(process, 'platform', {
|
|
value: 'linux',
|
|
});
|
|
|
|
windowManager.handleResizeMainWindow();
|
|
|
|
Object.defineProperty(process, 'platform', {
|
|
value: originalPlatform,
|
|
});
|
|
|
|
expect(view.setBounds).not.toHaveBeenCalled();
|
|
jest.runAllTimers();
|
|
expect(view.setBounds).toHaveBeenCalledWith({width: 1000, height: 900});
|
|
});
|
|
});
|
|
|
|
describe('handleWillResizeMainWindow', () => {
|
|
const windowManager = new WindowManager();
|
|
const view = {
|
|
setBounds: jest.fn(),
|
|
tab: {
|
|
url: 'http://server-1.com',
|
|
},
|
|
view: {
|
|
webContents: {
|
|
getURL: jest.fn(),
|
|
},
|
|
},
|
|
};
|
|
windowManager.viewManager = {
|
|
getCurrentView: () => view,
|
|
setLoadingScreenBounds: jest.fn(),
|
|
loadingScreenState: 3,
|
|
};
|
|
windowManager.mainWindow = {
|
|
getContentBounds: () => ({width: 1000, height: 900}),
|
|
getSize: () => [1000, 900],
|
|
};
|
|
windowManager.teamDropdown = {
|
|
updateWindowBounds: jest.fn(),
|
|
};
|
|
|
|
beforeEach(() => {
|
|
getAdjustedWindowBoundaries.mockImplementation((width, height) => ({width, height}));
|
|
});
|
|
|
|
afterEach(() => {
|
|
windowManager.isResizing = false;
|
|
jest.resetAllMocks();
|
|
});
|
|
|
|
it('should update loading screen and team dropdown bounds', () => {
|
|
const event = {preventDefault: jest.fn()};
|
|
windowManager.handleWillResizeMainWindow(event, {width: 800, height: 600});
|
|
expect(windowManager.viewManager.setLoadingScreenBounds).toHaveBeenCalled();
|
|
expect(windowManager.teamDropdown.updateWindowBounds).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should not resize if the app is already resizing', () => {
|
|
windowManager.isResizing = true;
|
|
const event = {preventDefault: jest.fn()};
|
|
windowManager.handleWillResizeMainWindow(event, {width: 800, height: 600});
|
|
expect(view.setBounds).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should use provided bounds', () => {
|
|
const event = {preventDefault: jest.fn()};
|
|
windowManager.handleWillResizeMainWindow(event, {width: 800, height: 600});
|
|
expect(windowManager.isResizing).toBe(true);
|
|
expect(view.setBounds).toHaveBeenCalledWith({width: 800, height: 600});
|
|
});
|
|
});
|
|
|
|
describe('handleResizedMainWindow', () => {
|
|
const windowManager = new WindowManager();
|
|
const view = {
|
|
setBounds: jest.fn(),
|
|
tab: {
|
|
url: 'http://server-1.com',
|
|
},
|
|
view: {
|
|
webContents: {
|
|
getURL: jest.fn(),
|
|
},
|
|
},
|
|
};
|
|
windowManager.mainWindow = {
|
|
getContentBounds: () => ({width: 800, height: 600}),
|
|
getSize: () => [1000, 900],
|
|
};
|
|
|
|
beforeEach(() => {
|
|
getAdjustedWindowBoundaries.mockImplementation((width, height) => ({width, height}));
|
|
});
|
|
|
|
afterEach(() => {
|
|
windowManager.isResizing = true;
|
|
jest.resetAllMocks();
|
|
});
|
|
|
|
it('should not handle bounds if no window available', () => {
|
|
windowManager.handleResizedMainWindow();
|
|
expect(windowManager.isResizing).toBe(false);
|
|
expect(view.setBounds).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should use getContentBounds when the platform is different to linux', () => {
|
|
windowManager.viewManager = {
|
|
getCurrentView: () => view,
|
|
};
|
|
|
|
const originalPlatform = process.platform;
|
|
Object.defineProperty(process, 'platform', {
|
|
value: 'windows',
|
|
});
|
|
|
|
windowManager.handleResizedMainWindow();
|
|
|
|
Object.defineProperty(process, 'platform', {
|
|
value: originalPlatform,
|
|
});
|
|
|
|
expect(windowManager.isResizing).toBe(false);
|
|
expect(view.setBounds).toHaveBeenCalledWith({width: 800, height: 600});
|
|
});
|
|
|
|
it('should use getSize when the platform is linux', () => {
|
|
const originalPlatform = process.platform;
|
|
Object.defineProperty(process, 'platform', {
|
|
value: 'linux',
|
|
});
|
|
|
|
windowManager.handleResizedMainWindow();
|
|
|
|
Object.defineProperty(process, 'platform', {
|
|
value: originalPlatform,
|
|
});
|
|
|
|
expect(windowManager.isResizing).toBe(false);
|
|
expect(view.setBounds).toHaveBeenCalledWith({width: 1000, height: 900});
|
|
});
|
|
});
|
|
|
|
describe('restoreMain', () => {
|
|
const windowManager = new WindowManager();
|
|
windowManager.mainWindow = {
|
|
isVisible: jest.fn(),
|
|
isMinimized: jest.fn(),
|
|
restore: jest.fn(),
|
|
show: jest.fn(),
|
|
focus: jest.fn(),
|
|
};
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
delete windowManager.settingsWindow;
|
|
});
|
|
|
|
it('should restore main window if minimized', () => {
|
|
windowManager.mainWindow.isMinimized.mockReturnValue(true);
|
|
windowManager.restoreMain();
|
|
expect(windowManager.mainWindow.restore).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should show main window if not visible or minimized', () => {
|
|
windowManager.mainWindow.isVisible.mockReturnValue(false);
|
|
windowManager.mainWindow.isMinimized.mockReturnValue(false);
|
|
windowManager.restoreMain();
|
|
expect(windowManager.mainWindow.show).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should focus main window if visible and not minimized', () => {
|
|
windowManager.mainWindow.isVisible.mockReturnValue(true);
|
|
windowManager.mainWindow.isMinimized.mockReturnValue(false);
|
|
windowManager.restoreMain();
|
|
expect(windowManager.mainWindow.focus).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should focus settings window regardless of main window state if it exists', () => {
|
|
windowManager.settingsWindow = {
|
|
focus: jest.fn(),
|
|
};
|
|
|
|
windowManager.mainWindow.isVisible.mockReturnValue(false);
|
|
windowManager.mainWindow.isMinimized.mockReturnValue(false);
|
|
windowManager.restoreMain();
|
|
expect(windowManager.settingsWindow.focus).toHaveBeenCalled();
|
|
windowManager.settingsWindow.focus.mockClear();
|
|
|
|
windowManager.mainWindow.isVisible.mockReturnValue(true);
|
|
windowManager.mainWindow.isMinimized.mockReturnValue(false);
|
|
windowManager.restoreMain();
|
|
expect(windowManager.settingsWindow.focus).toHaveBeenCalled();
|
|
windowManager.settingsWindow.focus.mockClear();
|
|
|
|
windowManager.mainWindow.isVisible.mockReturnValue(false);
|
|
windowManager.mainWindow.isMinimized.mockReturnValue(true);
|
|
windowManager.restoreMain();
|
|
expect(windowManager.settingsWindow.focus).toHaveBeenCalled();
|
|
windowManager.settingsWindow.focus.mockClear();
|
|
|
|
windowManager.mainWindow.isVisible.mockReturnValue(true);
|
|
windowManager.mainWindow.isMinimized.mockReturnValue(true);
|
|
windowManager.restoreMain();
|
|
expect(windowManager.settingsWindow.focus).toHaveBeenCalled();
|
|
windowManager.settingsWindow.focus.mockClear();
|
|
});
|
|
});
|
|
|
|
describe('flashFrame', () => {
|
|
const windowManager = new WindowManager();
|
|
windowManager.mainWindow = {
|
|
flashFrame: jest.fn(),
|
|
};
|
|
windowManager.settingsWindow = {
|
|
flashFrame: jest.fn(),
|
|
};
|
|
|
|
beforeEach(() => {
|
|
Config.notifications = {};
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
Config.notifications = {};
|
|
});
|
|
|
|
it('linux/windows - should not flash frame when config item is not set', () => {
|
|
const originalPlatform = process.platform;
|
|
Object.defineProperty(process, 'platform', {
|
|
value: 'linux',
|
|
});
|
|
windowManager.flashFrame(true);
|
|
Object.defineProperty(process, 'platform', {
|
|
value: originalPlatform,
|
|
});
|
|
expect(windowManager.mainWindow.flashFrame).not.toBeCalled();
|
|
expect(windowManager.settingsWindow.flashFrame).not.toBeCalled();
|
|
});
|
|
|
|
it('linux/windows - should flash frame when config item is set', () => {
|
|
Config.notifications = {
|
|
flashWindow: true,
|
|
};
|
|
const originalPlatform = process.platform;
|
|
Object.defineProperty(process, 'platform', {
|
|
value: 'linux',
|
|
});
|
|
windowManager.flashFrame(true);
|
|
Object.defineProperty(process, 'platform', {
|
|
value: originalPlatform,
|
|
});
|
|
expect(windowManager.mainWindow.flashFrame).toBeCalledWith(true);
|
|
});
|
|
|
|
it('mac - should not bounce icon when config item is not set', () => {
|
|
const originalPlatform = process.platform;
|
|
Object.defineProperty(process, 'platform', {
|
|
value: 'darwin',
|
|
});
|
|
windowManager.flashFrame(true);
|
|
Object.defineProperty(process, 'platform', {
|
|
value: originalPlatform,
|
|
});
|
|
expect(app.dock.bounce).not.toBeCalled();
|
|
});
|
|
|
|
it('mac - should bounce icon when config item is set', () => {
|
|
Config.notifications = {
|
|
bounceIcon: true,
|
|
bounceIconType: 'critical',
|
|
};
|
|
const originalPlatform = process.platform;
|
|
Object.defineProperty(process, 'platform', {
|
|
value: 'darwin',
|
|
});
|
|
windowManager.flashFrame(true);
|
|
Object.defineProperty(process, 'platform', {
|
|
value: originalPlatform,
|
|
});
|
|
expect(app.dock.bounce).toHaveBeenCalledWith('critical');
|
|
});
|
|
});
|
|
|
|
describe('handleDoubleClick', () => {
|
|
const windowManager = new WindowManager();
|
|
const mainWindow = {
|
|
isMinimized: jest.fn(),
|
|
restore: jest.fn(),
|
|
minimize: jest.fn(),
|
|
isMaximized: jest.fn(),
|
|
unmaximize: jest.fn(),
|
|
maximize: jest.fn(),
|
|
};
|
|
const settingsWindow = {
|
|
isMinimized: jest.fn(),
|
|
restore: jest.fn(),
|
|
minimize: jest.fn(),
|
|
isMaximized: jest.fn(),
|
|
unmaximize: jest.fn(),
|
|
maximize: jest.fn(),
|
|
};
|
|
|
|
beforeEach(() => {
|
|
systemPreferences.getUserDefault.mockReturnValue('Maximize');
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
delete windowManager.mainWindow;
|
|
delete windowManager.settingsWindow;
|
|
});
|
|
|
|
it('should do nothing when the windows arent set', () => {
|
|
windowManager.handleDoubleClick(null, 'settings');
|
|
expect(settingsWindow.isMaximized).not.toHaveBeenCalled();
|
|
|
|
windowManager.handleDoubleClick();
|
|
expect(mainWindow.isMaximized).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should maximize when not maximized and vice versa', () => {
|
|
windowManager.mainWindow = mainWindow;
|
|
|
|
windowManager.mainWindow.isMaximized.mockReturnValue(false);
|
|
windowManager.handleDoubleClick();
|
|
expect(mainWindow.maximize).toHaveBeenCalled();
|
|
|
|
windowManager.mainWindow.isMaximized.mockReturnValue(true);
|
|
windowManager.handleDoubleClick();
|
|
expect(mainWindow.unmaximize).toHaveBeenCalled();
|
|
});
|
|
|
|
it('mac - should minimize when not minimized and vice versa when setting is set', () => {
|
|
const originalPlatform = process.platform;
|
|
Object.defineProperty(process, 'platform', {
|
|
value: 'darwin',
|
|
});
|
|
windowManager.flashFrame(true);
|
|
|
|
systemPreferences.getUserDefault.mockReturnValue('Minimize');
|
|
windowManager.settingsWindow = settingsWindow;
|
|
|
|
windowManager.settingsWindow.isMinimized.mockReturnValue(false);
|
|
windowManager.handleDoubleClick(null, 'settings');
|
|
expect(settingsWindow.minimize).toHaveBeenCalled();
|
|
|
|
windowManager.settingsWindow.isMinimized.mockReturnValue(true);
|
|
windowManager.handleDoubleClick(null, 'settings');
|
|
expect(settingsWindow.restore).toHaveBeenCalled();
|
|
|
|
Object.defineProperty(process, 'platform', {
|
|
value: originalPlatform,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('switchServer', () => {
|
|
const windowManager = new WindowManager();
|
|
windowManager.viewManager = {
|
|
showByName: jest.fn(),
|
|
};
|
|
|
|
beforeEach(() => {
|
|
jest.useFakeTimers();
|
|
getTabViewName.mockImplementation((server, tab) => `${server}_${tab}`);
|
|
|
|
Config.teams = [
|
|
{
|
|
name: 'server-1',
|
|
order: 1,
|
|
tabs: [
|
|
{
|
|
name: 'tab-1',
|
|
order: 0,
|
|
isOpen: false,
|
|
},
|
|
{
|
|
name: 'tab-2',
|
|
order: 2,
|
|
isOpen: true,
|
|
},
|
|
{
|
|
name: 'tab-3',
|
|
order: 1,
|
|
isOpen: true,
|
|
},
|
|
],
|
|
}, {
|
|
name: 'server-2',
|
|
order: 0,
|
|
tabs: [
|
|
{
|
|
name: 'tab-1',
|
|
order: 0,
|
|
isOpen: false,
|
|
},
|
|
{
|
|
name: 'tab-2',
|
|
order: 2,
|
|
isOpen: true,
|
|
},
|
|
{
|
|
name: 'tab-3',
|
|
order: 1,
|
|
isOpen: true,
|
|
},
|
|
],
|
|
lastActiveTab: 2,
|
|
},
|
|
];
|
|
|
|
const map = Config.teams.reduce((arr, item) => {
|
|
item.tabs.forEach((tab) => {
|
|
arr.push([`${item.name}_${tab.name}`, {}]);
|
|
});
|
|
return arr;
|
|
}, []);
|
|
windowManager.viewManager.views = new Map(map);
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
Config.teams = [];
|
|
});
|
|
|
|
afterAll(() => {
|
|
jest.runOnlyPendingTimers();
|
|
jest.clearAllTimers();
|
|
jest.useRealTimers();
|
|
});
|
|
|
|
it('should do nothing if cannot find the server', () => {
|
|
windowManager.switchServer('server-3');
|
|
expect(getTabViewName).not.toBeCalled();
|
|
expect(windowManager.viewManager.showByName).not.toBeCalled();
|
|
});
|
|
|
|
it('should show first open tab in order when last active not defined', () => {
|
|
windowManager.switchServer('server-1');
|
|
expect(windowManager.viewManager.showByName).toHaveBeenCalledWith('server-1_tab-3');
|
|
});
|
|
|
|
it('should show last active tab of chosen server', () => {
|
|
windowManager.switchServer('server-2');
|
|
expect(windowManager.viewManager.showByName).toHaveBeenCalledWith('server-2_tab-2');
|
|
});
|
|
|
|
it('should wait for view to exist if specified', () => {
|
|
windowManager.viewManager.views.delete('server-1_tab-3');
|
|
windowManager.switchServer('server-1', true);
|
|
expect(windowManager.viewManager.showByName).not.toBeCalled();
|
|
|
|
jest.advanceTimersByTime(200);
|
|
expect(windowManager.viewManager.showByName).not.toBeCalled();
|
|
|
|
windowManager.viewManager.views.set('server-1_tab-3', {});
|
|
jest.advanceTimersByTime(200);
|
|
expect(windowManager.viewManager.showByName).toBeCalledWith('server-1_tab-3');
|
|
});
|
|
});
|
|
|
|
describe('handleHistory', () => {
|
|
const windowManager = new WindowManager();
|
|
windowManager.viewManager = {
|
|
getCurrentView: jest.fn(),
|
|
};
|
|
|
|
it('should only go to offset if it can', () => {
|
|
const view = {
|
|
view: {
|
|
webContents: {
|
|
goToOffset: jest.fn(),
|
|
canGoToOffset: () => false,
|
|
},
|
|
},
|
|
};
|
|
windowManager.viewManager.getCurrentView.mockReturnValue(view);
|
|
|
|
windowManager.handleHistory(null, 1);
|
|
expect(view.view.webContents.goToOffset).not.toBeCalled();
|
|
|
|
windowManager.viewManager.getCurrentView.mockReturnValue({
|
|
...view,
|
|
view: {
|
|
...view.view,
|
|
webContents: {
|
|
...view.view.webContents,
|
|
canGoToOffset: () => true,
|
|
},
|
|
},
|
|
});
|
|
|
|
windowManager.handleHistory(null, 1);
|
|
expect(view.view.webContents.goToOffset).toBeCalled();
|
|
});
|
|
|
|
it('should load base URL if an error occurs', () => {
|
|
const view = {
|
|
load: jest.fn(),
|
|
tab: {
|
|
url: 'http://server-1.com',
|
|
},
|
|
view: {
|
|
webContents: {
|
|
goToOffset: jest.fn(),
|
|
canGoToOffset: () => true,
|
|
},
|
|
},
|
|
};
|
|
view.view.webContents.goToOffset.mockImplementation(() => {
|
|
throw new Error('hi');
|
|
});
|
|
windowManager.viewManager.getCurrentView.mockReturnValue(view);
|
|
|
|
windowManager.handleHistory(null, 1);
|
|
expect(view.load).toBeCalledWith('http://server-1.com');
|
|
});
|
|
});
|
|
|
|
describe('selectTab', () => {
|
|
const windowManager = new WindowManager();
|
|
windowManager.viewManager = {
|
|
getCurrentView: jest.fn(),
|
|
};
|
|
windowManager.switchTab = jest.fn();
|
|
|
|
beforeEach(() => {
|
|
Config.teams = [
|
|
{
|
|
name: 'server-1',
|
|
order: 1,
|
|
tabs: [
|
|
{
|
|
name: 'tab-1',
|
|
order: 0,
|
|
isOpen: false,
|
|
},
|
|
{
|
|
name: 'tab-2',
|
|
order: 2,
|
|
isOpen: true,
|
|
},
|
|
{
|
|
name: 'tab-3',
|
|
order: 1,
|
|
isOpen: true,
|
|
},
|
|
],
|
|
},
|
|
];
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
Config.teams = [];
|
|
});
|
|
|
|
it('should select next server when open', () => {
|
|
windowManager.viewManager.getCurrentView.mockReturnValue({
|
|
tab: {
|
|
server: {
|
|
name: 'server-1',
|
|
},
|
|
type: 'tab-3',
|
|
},
|
|
});
|
|
|
|
windowManager.selectTab((order) => order + 1);
|
|
expect(windowManager.switchTab).toBeCalledWith('server-1', 'tab-2');
|
|
});
|
|
|
|
it('should select previous server when open', () => {
|
|
windowManager.viewManager.getCurrentView.mockReturnValue({
|
|
tab: {
|
|
server: {
|
|
name: 'server-1',
|
|
},
|
|
type: 'tab-2',
|
|
},
|
|
});
|
|
|
|
windowManager.selectTab((order, length) => (length + (order - 1)));
|
|
expect(windowManager.switchTab).toBeCalledWith('server-1', 'tab-3');
|
|
});
|
|
|
|
it('should skip over closed tab', () => {
|
|
windowManager.viewManager.getCurrentView.mockReturnValue({
|
|
tab: {
|
|
server: {
|
|
name: 'server-1',
|
|
},
|
|
type: 'tab-2',
|
|
},
|
|
});
|
|
windowManager.selectTab((order) => order + 1);
|
|
expect(windowManager.switchTab).toBeCalledWith('server-1', 'tab-3');
|
|
});
|
|
});
|
|
|
|
describe('handleBrowserHistoryPush', () => {
|
|
const windowManager = new WindowManager();
|
|
const view1 = {
|
|
name: 'server-1_tab-messaging',
|
|
isLoggedIn: true,
|
|
tab: {
|
|
type: TAB_MESSAGING,
|
|
server: {
|
|
url: 'http://server-1.com',
|
|
},
|
|
},
|
|
view: {
|
|
webContents: {
|
|
send: jest.fn(),
|
|
},
|
|
},
|
|
};
|
|
const view2 = {
|
|
...view1,
|
|
name: 'server-1_other_type_1',
|
|
tab: {
|
|
...view1.tab,
|
|
type: 'other_type_1',
|
|
},
|
|
view: {
|
|
webContents: {
|
|
send: jest.fn(),
|
|
},
|
|
},
|
|
};
|
|
const view3 = {
|
|
...view1,
|
|
name: 'server-1_other_type_2',
|
|
tab: {
|
|
...view1.tab,
|
|
type: 'other_type_2',
|
|
},
|
|
view: {
|
|
webContents: {
|
|
send: jest.fn(),
|
|
},
|
|
},
|
|
};
|
|
windowManager.viewManager = {
|
|
views: new Map([
|
|
['server-1_tab-messaging', view1],
|
|
['server-1_other_type_1', view2],
|
|
]),
|
|
closedViews: new Map([
|
|
['server-1_other_type_2', view3],
|
|
]),
|
|
openClosedTab: jest.fn(),
|
|
showByName: jest.fn(),
|
|
getViewByURL: jest.fn(),
|
|
};
|
|
windowManager.handleBrowserHistoryButton = jest.fn();
|
|
|
|
beforeEach(() => {
|
|
Config.teams = [
|
|
{
|
|
name: 'server-1',
|
|
url: 'http://server-1.com',
|
|
order: 0,
|
|
tabs: [
|
|
{
|
|
name: 'tab-messaging',
|
|
order: 0,
|
|
isOpen: true,
|
|
},
|
|
{
|
|
name: 'other_type_1',
|
|
order: 2,
|
|
isOpen: true,
|
|
},
|
|
{
|
|
name: 'other_type_2',
|
|
order: 1,
|
|
isOpen: false,
|
|
},
|
|
],
|
|
},
|
|
];
|
|
urlUtils.cleanPathName.mockImplementation((base, path) => path);
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
Config.teams = [];
|
|
});
|
|
|
|
it('should open closed view if pushing to it', () => {
|
|
windowManager.viewManager.getViewByURL.mockReturnValue({name: 'server-1_other_type_2'});
|
|
windowManager.viewManager.openClosedTab.mockImplementation((name) => {
|
|
const view = windowManager.viewManager.closedViews.get(name);
|
|
windowManager.viewManager.closedViews.delete(name);
|
|
windowManager.viewManager.views.set(name, view);
|
|
});
|
|
|
|
windowManager.handleBrowserHistoryPush(null, 'server-1_tab-messaging', '/other_type_2/subpath');
|
|
expect(windowManager.viewManager.openClosedTab).toBeCalledWith('server-1_other_type_2', 'http://server-1.com/other_type_2/subpath');
|
|
});
|
|
|
|
it('should open redirect view if different from current view', () => {
|
|
windowManager.viewManager.getViewByURL.mockReturnValue({name: 'server-1_other_type_1'});
|
|
windowManager.handleBrowserHistoryPush(null, 'server-1_tab-messaging', '/other_type_1/subpath');
|
|
expect(windowManager.viewManager.showByName).toBeCalledWith('server-1_other_type_1');
|
|
});
|
|
|
|
it('should ignore redirects to "/" to Messages from other tabs', () => {
|
|
windowManager.viewManager.getViewByURL.mockReturnValue({name: 'server-1_tab-messaging'});
|
|
windowManager.handleBrowserHistoryPush(null, 'server-1_other_type_1', '/');
|
|
expect(view1.view.webContents.send).not.toBeCalled();
|
|
});
|
|
});
|
|
|
|
describe('handleBrowserHistoryButton', () => {
|
|
const windowManager = new WindowManager();
|
|
const view1 = {
|
|
name: 'server-1_tab-messaging',
|
|
isLoggedIn: true,
|
|
isAtRoot: true,
|
|
tab: {
|
|
type: TAB_MESSAGING,
|
|
server: {
|
|
url: 'http://server-1.com',
|
|
},
|
|
url: new URL('http://server-1.com'),
|
|
},
|
|
view: {
|
|
webContents: {
|
|
canGoBack: jest.fn(),
|
|
canGoForward: jest.fn(),
|
|
clearHistory: jest.fn(),
|
|
send: jest.fn(),
|
|
getURL: jest.fn(),
|
|
},
|
|
},
|
|
};
|
|
windowManager.viewManager = {
|
|
views: new Map([
|
|
['server-1_tab-messaging', view1],
|
|
]),
|
|
};
|
|
|
|
beforeEach(() => {
|
|
Config.teams = [
|
|
{
|
|
name: 'server-1',
|
|
url: 'http://server-1.com',
|
|
order: 0,
|
|
tabs: [
|
|
{
|
|
name: 'tab-messaging',
|
|
order: 0,
|
|
isOpen: true,
|
|
},
|
|
],
|
|
},
|
|
];
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
Config.teams = [];
|
|
view1.isAtRoot = true;
|
|
});
|
|
|
|
it('should erase history and set isAtRoot when navigating to root URL', () => {
|
|
view1.isAtRoot = false;
|
|
view1.view.webContents.getURL.mockReturnValue(view1.tab.url.toString());
|
|
windowManager.handleBrowserHistoryButton(null, 'server-1_tab-messaging');
|
|
expect(view1.view.webContents.clearHistory).toHaveBeenCalled();
|
|
expect(view1.isAtRoot).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('createCallsWidgetWindow', () => {
|
|
const view = {
|
|
name: 'server-1_tab-messaging',
|
|
serverInfo: {
|
|
server: {
|
|
url: new URL('http://server-1.com'),
|
|
},
|
|
},
|
|
};
|
|
|
|
beforeEach(() => {
|
|
CallsWidgetWindow.mockImplementation(() => {
|
|
return {
|
|
win: {
|
|
isDestroyed: jest.fn(() => true),
|
|
},
|
|
on: jest.fn(),
|
|
close: jest.fn(),
|
|
};
|
|
});
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
});
|
|
|
|
const windowManager = new WindowManager();
|
|
windowManager.viewManager = {
|
|
views: new Map([
|
|
['server-1_tab-messaging', view],
|
|
]),
|
|
};
|
|
|
|
it('should create calls widget window', async () => {
|
|
expect(windowManager.callsWidgetWindow).toBeUndefined();
|
|
await windowManager.createCallsWidgetWindow('server-1_tab-messaging', {callID: 'test'});
|
|
expect(windowManager.callsWidgetWindow).toBeDefined();
|
|
});
|
|
|
|
it('should not create a new window if call is the same', async () => {
|
|
const widgetWindow = windowManager.callsWidgetWindow;
|
|
expect(widgetWindow).toBeDefined();
|
|
widgetWindow.getCallID = jest.fn(() => 'test');
|
|
await windowManager.createCallsWidgetWindow('server-1_tab-messaging', {callID: 'test'});
|
|
expect(windowManager.callsWidgetWindow).toEqual(widgetWindow);
|
|
});
|
|
|
|
it('should create a new window if switching calls', async () => {
|
|
const widgetWindow = windowManager.callsWidgetWindow;
|
|
expect(widgetWindow).toBeDefined();
|
|
widgetWindow.getCallID = jest.fn(() => 'test');
|
|
await windowManager.createCallsWidgetWindow('server-1_tab-messaging', {callID: 'test2'});
|
|
expect(windowManager.callsWidgetWindow).not.toEqual(widgetWindow);
|
|
});
|
|
});
|
|
|
|
describe('handleGetDesktopSources', () => {
|
|
const windowManager = new WindowManager();
|
|
windowManager.viewManager = {
|
|
showByName: jest.fn(),
|
|
getCurrentView: jest.fn(),
|
|
};
|
|
|
|
beforeEach(() => {
|
|
CallsWidgetWindow.mockImplementation(() => {
|
|
return {
|
|
isAllowedEvent: jest.fn().mockReturnValue(true),
|
|
win: {
|
|
webContents: {
|
|
send: jest.fn(),
|
|
},
|
|
},
|
|
};
|
|
});
|
|
|
|
windowManager.callsWidgetWindow = new CallsWidgetWindow();
|
|
|
|
Config.teams = [
|
|
{
|
|
name: 'server-1',
|
|
order: 1,
|
|
tabs: [
|
|
{
|
|
name: 'tab-1',
|
|
order: 0,
|
|
isOpen: false,
|
|
},
|
|
{
|
|
name: 'tab-2',
|
|
order: 2,
|
|
isOpen: true,
|
|
},
|
|
],
|
|
}, {
|
|
name: 'server-2',
|
|
order: 0,
|
|
tabs: [
|
|
{
|
|
name: 'tab-1',
|
|
order: 0,
|
|
isOpen: false,
|
|
},
|
|
{
|
|
name: 'tab-2',
|
|
order: 2,
|
|
isOpen: true,
|
|
},
|
|
],
|
|
lastActiveTab: 2,
|
|
},
|
|
];
|
|
|
|
const map = Config.teams.reduce((arr, item) => {
|
|
item.tabs.forEach((tab) => {
|
|
arr.push([`${item.name}_${tab.name}`, {
|
|
view: {
|
|
webContents: {
|
|
send: jest.fn(),
|
|
},
|
|
},
|
|
}]);
|
|
});
|
|
return arr;
|
|
}, []);
|
|
windowManager.viewManager.views = new Map(map);
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
Config.teams = [];
|
|
windowManager.missingScreensharePermissions = undefined;
|
|
});
|
|
|
|
it('should send sources back', async () => {
|
|
jest.spyOn(desktopCapturer, 'getSources').mockResolvedValue([
|
|
{
|
|
id: 'screen0',
|
|
thumbnail: {
|
|
toDataURL: jest.fn(),
|
|
},
|
|
},
|
|
{
|
|
id: 'window0',
|
|
thumbnail: {
|
|
toDataURL: jest.fn(),
|
|
},
|
|
},
|
|
]);
|
|
|
|
await windowManager.handleGetDesktopSources('server-1_tab-1', null);
|
|
|
|
expect(windowManager.viewManager.views.get('server-1_tab-1').view.webContents.send).toHaveBeenCalledWith('desktop-sources-result', [
|
|
{
|
|
id: 'screen0',
|
|
},
|
|
{
|
|
id: 'window0',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('should send error with no sources', async () => {
|
|
jest.spyOn(desktopCapturer, 'getSources').mockResolvedValue([]);
|
|
await windowManager.handleGetDesktopSources('server-2_tab-1', null);
|
|
expect(windowManager.callsWidgetWindow.win.webContents.send).toHaveBeenCalledWith('calls-error', {
|
|
err: 'screen-permissions',
|
|
});
|
|
expect(windowManager.viewManager.views.get('server-2_tab-1').view.webContents.send).toHaveBeenCalledWith('calls-error', {
|
|
err: 'screen-permissions',
|
|
});
|
|
expect(windowManager.callsWidgetWindow.win.webContents.send).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('should send error with no permissions', async () => {
|
|
jest.spyOn(desktopCapturer, 'getSources').mockResolvedValue([
|
|
{
|
|
id: 'screen0',
|
|
thumbnail: {
|
|
toDataURL: jest.fn(),
|
|
},
|
|
},
|
|
]);
|
|
jest.spyOn(systemPreferences, 'getMediaAccessStatus').mockReturnValue('denied');
|
|
|
|
await windowManager.handleGetDesktopSources('server-1_tab-1', null);
|
|
|
|
expect(systemPreferences.getMediaAccessStatus).toHaveBeenCalledWith('screen');
|
|
expect(windowManager.callsWidgetWindow.win.webContents.send).toHaveBeenCalledWith('calls-error', {
|
|
err: 'screen-permissions',
|
|
});
|
|
expect(windowManager.viewManager.views.get('server-1_tab-1').view.webContents.send).toHaveBeenCalledWith('calls-error', {
|
|
err: 'screen-permissions',
|
|
});
|
|
expect(windowManager.viewManager.views.get('server-1_tab-1').view.webContents.send).toHaveBeenCalledTimes(1);
|
|
expect(windowManager.callsWidgetWindow.win.webContents.send).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('macos - no permissions', async () => {
|
|
const originalPlatform = process.platform;
|
|
Object.defineProperty(process, 'platform', {
|
|
value: 'darwin',
|
|
});
|
|
|
|
jest.spyOn(desktopCapturer, 'getSources').mockResolvedValue([
|
|
{
|
|
id: 'screen0',
|
|
thumbnail: {
|
|
toDataURL: jest.fn(),
|
|
},
|
|
},
|
|
]);
|
|
jest.spyOn(systemPreferences, 'getMediaAccessStatus').mockReturnValue('denied');
|
|
|
|
await windowManager.handleGetDesktopSources('server-1_tab-1', null);
|
|
|
|
expect(windowManager.missingScreensharePermissions).toBe(true);
|
|
expect(resetScreensharePermissionsMacOS).toHaveBeenCalledTimes(1);
|
|
expect(openScreensharePermissionsSettingsMacOS).toHaveBeenCalledTimes(0);
|
|
expect(windowManager.callsWidgetWindow.win.webContents.send).toHaveBeenCalledWith('calls-error', {
|
|
err: 'screen-permissions',
|
|
});
|
|
expect(windowManager.viewManager.views.get('server-1_tab-1').view.webContents.send).toHaveBeenCalledWith('calls-error', {
|
|
err: 'screen-permissions',
|
|
});
|
|
|
|
await windowManager.handleGetDesktopSources('server-1_tab-1', null);
|
|
|
|
expect(resetScreensharePermissionsMacOS).toHaveBeenCalledTimes(2);
|
|
expect(openScreensharePermissionsSettingsMacOS).toHaveBeenCalledTimes(1);
|
|
|
|
Object.defineProperty(process, 'platform', {
|
|
value: originalPlatform,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('handleDesktopSourcesModalRequest', () => {
|
|
const windowManager = new WindowManager();
|
|
windowManager.switchServer = jest.fn();
|
|
windowManager.viewManager = {
|
|
showByName: jest.fn(),
|
|
getCurrentView: jest.fn(),
|
|
};
|
|
|
|
beforeEach(() => {
|
|
CallsWidgetWindow.mockImplementation(() => {
|
|
return {
|
|
getServerName: () => 'server-1',
|
|
getMainView: jest.fn().mockReturnValue({
|
|
view: {
|
|
webContents: {
|
|
send: jest.fn(),
|
|
},
|
|
},
|
|
}),
|
|
};
|
|
});
|
|
|
|
Config.teams = [
|
|
{
|
|
name: 'server-1',
|
|
order: 1,
|
|
tabs: [
|
|
{
|
|
name: 'tab-1',
|
|
order: 0,
|
|
isOpen: false,
|
|
},
|
|
{
|
|
name: 'tab-2',
|
|
order: 2,
|
|
isOpen: true,
|
|
},
|
|
],
|
|
}, {
|
|
name: 'server-2',
|
|
order: 0,
|
|
tabs: [
|
|
{
|
|
name: 'tab-1',
|
|
order: 0,
|
|
isOpen: false,
|
|
},
|
|
{
|
|
name: 'tab-2',
|
|
order: 2,
|
|
isOpen: true,
|
|
},
|
|
],
|
|
lastActiveTab: 2,
|
|
},
|
|
];
|
|
|
|
const map = Config.teams.reduce((arr, item) => {
|
|
item.tabs.forEach((tab) => {
|
|
arr.push([`${item.name}_${tab.name}`, {}]);
|
|
});
|
|
return arr;
|
|
}, []);
|
|
windowManager.viewManager.views = new Map(map);
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
Config.teams = [];
|
|
});
|
|
|
|
it('should switch server', () => {
|
|
windowManager.callsWidgetWindow = new CallsWidgetWindow();
|
|
windowManager.handleDesktopSourcesModalRequest();
|
|
expect(windowManager.switchServer).toHaveBeenCalledWith('server-1');
|
|
});
|
|
});
|
|
|
|
describe('handleCallsWidgetChannelLinkClick', () => {
|
|
const windowManager = new WindowManager();
|
|
windowManager.switchServer = jest.fn();
|
|
windowManager.viewManager = {
|
|
showByName: jest.fn(),
|
|
getCurrentView: jest.fn(),
|
|
};
|
|
|
|
beforeEach(() => {
|
|
CallsWidgetWindow.mockImplementation(() => {
|
|
return {
|
|
getServerName: () => 'server-2',
|
|
getMainView: jest.fn().mockReturnValue({
|
|
view: {
|
|
webContents: {
|
|
send: jest.fn(),
|
|
},
|
|
},
|
|
}),
|
|
getChannelURL: jest.fn(),
|
|
};
|
|
});
|
|
|
|
Config.teams = [
|
|
{
|
|
name: 'server-1',
|
|
order: 1,
|
|
tabs: [
|
|
{
|
|
name: 'tab-1',
|
|
order: 0,
|
|
isOpen: false,
|
|
},
|
|
{
|
|
name: 'tab-2',
|
|
order: 2,
|
|
isOpen: true,
|
|
},
|
|
],
|
|
}, {
|
|
name: 'server-2',
|
|
order: 0,
|
|
tabs: [
|
|
{
|
|
name: 'tab-1',
|
|
order: 0,
|
|
isOpen: false,
|
|
},
|
|
{
|
|
name: 'tab-2',
|
|
order: 2,
|
|
isOpen: true,
|
|
},
|
|
],
|
|
lastActiveTab: 2,
|
|
},
|
|
];
|
|
|
|
const map = Config.teams.reduce((arr, item) => {
|
|
item.tabs.forEach((tab) => {
|
|
arr.push([`${item.name}_${tab.name}`, {}]);
|
|
});
|
|
return arr;
|
|
}, []);
|
|
windowManager.viewManager.views = new Map(map);
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
Config.teams = [];
|
|
});
|
|
|
|
it('should switch server', () => {
|
|
windowManager.callsWidgetWindow = new CallsWidgetWindow();
|
|
windowManager.handleCallsWidgetChannelLinkClick();
|
|
expect(windowManager.switchServer).toHaveBeenCalledWith('server-2');
|
|
});
|
|
});
|
|
|
|
describe('handleCallsError', () => {
|
|
const windowManager = new WindowManager();
|
|
windowManager.switchServer = jest.fn();
|
|
windowManager.mainWindow = {
|
|
focus: jest.fn(),
|
|
};
|
|
|
|
beforeEach(() => {
|
|
CallsWidgetWindow.mockImplementation(() => {
|
|
return {
|
|
getServerName: () => 'server-2',
|
|
getMainView: jest.fn().mockReturnValue({
|
|
view: {
|
|
webContents: {
|
|
send: jest.fn(),
|
|
},
|
|
},
|
|
}),
|
|
};
|
|
});
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
Config.teams = [];
|
|
});
|
|
|
|
it('should focus view and propagate error to main view', () => {
|
|
windowManager.callsWidgetWindow = new CallsWidgetWindow();
|
|
windowManager.handleCallsError('', {err: 'client-error'});
|
|
expect(windowManager.switchServer).toHaveBeenCalledWith('server-2');
|
|
expect(windowManager.mainWindow.focus).toHaveBeenCalled();
|
|
expect(windowManager.callsWidgetWindow.getMainView().view.webContents.send).toHaveBeenCalledWith('calls-error', {err: 'client-error'});
|
|
});
|
|
});
|
|
|
|
describe('handleCallsLinkClick', () => {
|
|
const windowManager = new WindowManager();
|
|
windowManager.switchServer = jest.fn();
|
|
const view1 = {
|
|
view: {
|
|
webContents: {
|
|
send: jest.fn(),
|
|
},
|
|
},
|
|
};
|
|
windowManager.viewManager = {
|
|
views: new Map([
|
|
['server-1_tab-messaging', view1],
|
|
]),
|
|
};
|
|
|
|
beforeEach(() => {
|
|
CallsWidgetWindow.mockImplementation(() => {
|
|
return {
|
|
getServerName: () => 'server-1',
|
|
getMainView: jest.fn().mockReturnValue(view1),
|
|
};
|
|
});
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
Config.teams = [];
|
|
});
|
|
|
|
it('should pass through the click link to browser history push', () => {
|
|
windowManager.callsWidgetWindow = new CallsWidgetWindow();
|
|
windowManager.handleCallsLinkClick('', {link: '/other/subpath'});
|
|
expect(windowManager.switchServer).toHaveBeenCalledWith('server-1');
|
|
expect(view1.view.webContents.send).toBeCalledWith('browser-history-push', '/other/subpath');
|
|
});
|
|
});
|
|
|
|
describe('getServerURLFromWebContentsId', () => {
|
|
const view = {
|
|
name: 'server-1_tab-messaging',
|
|
serverInfo: {
|
|
server: {
|
|
url: new URL('http://server-1.com'),
|
|
},
|
|
},
|
|
};
|
|
const windowManager = new WindowManager();
|
|
windowManager.viewManager = {
|
|
views: new Map([
|
|
['server-1_tab-messaging', view],
|
|
]),
|
|
findViewByWebContent: jest.fn(),
|
|
};
|
|
|
|
it('should return calls widget URL', () => {
|
|
CallsWidgetWindow.mockImplementation(() => {
|
|
return {
|
|
on: jest.fn(),
|
|
getURL: jest.fn(() => 'http://localhost:8065'),
|
|
getWebContentsId: jest.fn(() => 'callsID'),
|
|
};
|
|
});
|
|
|
|
windowManager.createCallsWidgetWindow('server-1_tab-messaging', 'http://localhost:8065', {callID: 'test'});
|
|
expect(windowManager.getServerURLFromWebContentsId('callsID')).toBe(windowManager.callsWidgetWindow.getURL());
|
|
});
|
|
});
|
|
|
|
describe('genCallsEventHandler', () => {
|
|
const windowManager = new WindowManager();
|
|
|
|
const handler = jest.fn();
|
|
|
|
it('should call handler if callsWidgetWindow is not defined', () => {
|
|
windowManager.genCallsEventHandler(handler)();
|
|
expect(handler).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('should not call handler if source is not allowed', () => {
|
|
CallsWidgetWindow.mockImplementation(() => {
|
|
return {
|
|
isAllowedEvent: jest.fn().mockReturnValue(false),
|
|
};
|
|
});
|
|
|
|
windowManager.callsWidgetWindow = new CallsWidgetWindow();
|
|
windowManager.genCallsEventHandler(handler)();
|
|
expect(handler).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should call handler if source is allowed', () => {
|
|
CallsWidgetWindow.mockImplementation(() => {
|
|
return {
|
|
isAllowedEvent: jest.fn().mockReturnValue(true),
|
|
};
|
|
});
|
|
|
|
windowManager.callsWidgetWindow = new CallsWidgetWindow();
|
|
windowManager.genCallsEventHandler(handler)();
|
|
expect(handler).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|
|
});
|