MM-49079 - Calls: process link clicks from Calls popout (#2558)
* process link clicks from Calls popout * add a mock for windows tests
This commit is contained in:

committed by
GitHub

parent
7127ec153a
commit
ec8e0b9cc2
@@ -135,6 +135,7 @@ export const CALLS_LEAVE_CALL = 'calls-leave-call';
|
|||||||
export const CALLS_WIDGET_RESIZE = 'calls-widget-resize';
|
export const CALLS_WIDGET_RESIZE = 'calls-widget-resize';
|
||||||
export const CALLS_WIDGET_SHARE_SCREEN = 'calls-widget-share-screen';
|
export const CALLS_WIDGET_SHARE_SCREEN = 'calls-widget-share-screen';
|
||||||
export const CALLS_WIDGET_CHANNEL_LINK_CLICK = 'calls-widget-channel-link-click';
|
export const CALLS_WIDGET_CHANNEL_LINK_CLICK = 'calls-widget-channel-link-click';
|
||||||
|
export const CALLS_LINK_CLICK = 'calls-link-click';
|
||||||
export const CALLS_JOINED_CALL = 'calls-joined-call';
|
export const CALLS_JOINED_CALL = 'calls-joined-call';
|
||||||
export const CALLS_POPOUT_FOCUS = 'calls-popout-focus';
|
export const CALLS_POPOUT_FOCUS = 'calls-popout-focus';
|
||||||
export const CALLS_ERROR = 'calls-error';
|
export const CALLS_ERROR = 'calls-error';
|
||||||
|
@@ -16,6 +16,7 @@ import {
|
|||||||
DESKTOP_SOURCES_RESULT,
|
DESKTOP_SOURCES_RESULT,
|
||||||
DESKTOP_SOURCES_MODAL_REQUEST,
|
DESKTOP_SOURCES_MODAL_REQUEST,
|
||||||
DISPATCH_GET_DESKTOP_SOURCES,
|
DISPATCH_GET_DESKTOP_SOURCES,
|
||||||
|
CALLS_LINK_CLICK,
|
||||||
} from 'common/communication';
|
} from 'common/communication';
|
||||||
|
|
||||||
window.addEventListener('message', ({origin, data = {}} = {}) => {
|
window.addEventListener('message', ({origin, data = {}} = {}) => {
|
||||||
@@ -47,6 +48,7 @@ window.addEventListener('message', ({origin, data = {}} = {}) => {
|
|||||||
}
|
}
|
||||||
case DESKTOP_SOURCES_MODAL_REQUEST:
|
case DESKTOP_SOURCES_MODAL_REQUEST:
|
||||||
case CALLS_WIDGET_CHANNEL_LINK_CLICK:
|
case CALLS_WIDGET_CHANNEL_LINK_CLICK:
|
||||||
|
case CALLS_LINK_CLICK:
|
||||||
case CALLS_WIDGET_RESIZE:
|
case CALLS_WIDGET_RESIZE:
|
||||||
case CALLS_JOINED_CALL:
|
case CALLS_JOINED_CALL:
|
||||||
case CALLS_POPOUT_FOCUS:
|
case CALLS_POPOUT_FOCUS:
|
||||||
|
@@ -10,17 +10,26 @@ import {
|
|||||||
MINIMUM_CALLS_WIDGET_HEIGHT,
|
MINIMUM_CALLS_WIDGET_HEIGHT,
|
||||||
CALLS_PLUGIN_ID,
|
CALLS_PLUGIN_ID,
|
||||||
} from 'common/utils/constants';
|
} from 'common/utils/constants';
|
||||||
|
import WebContentsEventManager from '../views/webContentEvents';
|
||||||
|
|
||||||
import CallsWidgetWindow from './callsWidgetWindow';
|
import CallsWidgetWindow from './callsWidgetWindow';
|
||||||
|
|
||||||
jest.mock('electron', () => ({
|
jest.mock('electron', () => ({
|
||||||
|
app: {
|
||||||
|
getAppPath: () => '/path/to/app',
|
||||||
|
},
|
||||||
BrowserWindow: jest.fn(),
|
BrowserWindow: jest.fn(),
|
||||||
ipcMain: {
|
ipcMain: {
|
||||||
on: jest.fn(),
|
on: jest.fn(),
|
||||||
off: jest.fn(),
|
off: jest.fn(),
|
||||||
|
handle: jest.fn(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
jest.mock('../views/webContentEvents', () => ({
|
||||||
|
generateNewWindowListener: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('main/windows/callsWidgetWindow', () => {
|
describe('main/windows/callsWidgetWindow', () => {
|
||||||
describe('create CallsWidgetWindow', () => {
|
describe('create CallsWidgetWindow', () => {
|
||||||
const widgetConfig = {
|
const widgetConfig = {
|
||||||
@@ -330,9 +339,7 @@ describe('main/windows/callsWidgetWindow', () => {
|
|||||||
send: jest.fn(),
|
send: jest.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let isMinimized = false;
|
|
||||||
baseWindow.restore = jest.fn();
|
baseWindow.restore = jest.fn();
|
||||||
baseWindow.isMinimized = jest.fn(() => isMinimized);
|
|
||||||
|
|
||||||
const widgetWindow = new CallsWidgetWindow(mainWindow, mainView, widgetConfig);
|
const widgetWindow = new CallsWidgetWindow(mainWindow, mainView, widgetConfig);
|
||||||
|
|
||||||
@@ -341,19 +348,30 @@ describe('main/windows/callsWidgetWindow', () => {
|
|||||||
|
|
||||||
expect(widgetWindow.popOut).toBeNull();
|
expect(widgetWindow.popOut).toBeNull();
|
||||||
|
|
||||||
const popOut = new BrowserWindow();
|
const popOut = new EventEmitter();
|
||||||
|
popOut.webContents = {
|
||||||
|
setWindowOpenHandler: jest.fn(),
|
||||||
|
on: jest.fn(),
|
||||||
|
id: 'webContentsId',
|
||||||
|
};
|
||||||
|
popOut.focus = jest.fn();
|
||||||
|
popOut.restore = jest.fn();
|
||||||
|
popOut.isMinimized = jest.fn().mockReturnValue(false);
|
||||||
|
|
||||||
widgetWindow.onPopOutFocus();
|
widgetWindow.onPopOutFocus();
|
||||||
expect(popOut.focus).not.toHaveBeenCalled();
|
expect(popOut.focus).not.toHaveBeenCalled();
|
||||||
expect(popOut.restore).not.toHaveBeenCalled();
|
expect(popOut.restore).not.toHaveBeenCalled();
|
||||||
|
|
||||||
widgetWindow.onPopOutCreate(popOut);
|
widgetWindow.onPopOutCreate(popOut);
|
||||||
expect(widgetWindow.popOut).toBe(popOut);
|
expect(widgetWindow.popOut).toBe(popOut);
|
||||||
|
expect(popOut.webContents.setWindowOpenHandler).toHaveBeenCalled();
|
||||||
|
expect(WebContentsEventManager.generateNewWindowListener).toHaveBeenCalledWith('webContentsId', true);
|
||||||
|
|
||||||
widgetWindow.onPopOutFocus();
|
widgetWindow.onPopOutFocus();
|
||||||
expect(popOut.focus).toHaveBeenCalled();
|
expect(popOut.focus).toHaveBeenCalled();
|
||||||
expect(popOut.restore).not.toHaveBeenCalled();
|
expect(popOut.restore).not.toHaveBeenCalled();
|
||||||
|
|
||||||
isMinimized = true;
|
popOut.isMinimized = jest.fn().mockReturnValue(true);
|
||||||
widgetWindow.onPopOutFocus();
|
widgetWindow.onPopOutFocus();
|
||||||
expect(popOut.focus).toHaveBeenCalled();
|
expect(popOut.focus).toHaveBeenCalled();
|
||||||
expect(popOut.restore).toHaveBeenCalled();
|
expect(popOut.restore).toHaveBeenCalled();
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import url from 'url';
|
import url from 'url';
|
||||||
|
|
||||||
import {EventEmitter} from 'events';
|
import {EventEmitter} from 'events';
|
||||||
import {BrowserWindow, Rectangle, ipcMain, IpcMainEvent} from 'electron';
|
import {BrowserWindow, Rectangle, ipcMain, IpcMainEvent} from 'electron';
|
||||||
import log from 'electron-log';
|
import log from 'electron-log';
|
||||||
@@ -31,6 +30,8 @@ import {
|
|||||||
CALLS_WIDGET_RESIZE,
|
CALLS_WIDGET_RESIZE,
|
||||||
CALLS_WIDGET_SHARE_SCREEN,
|
CALLS_WIDGET_SHARE_SCREEN,
|
||||||
} from 'common/communication';
|
} from 'common/communication';
|
||||||
|
import webContentsEventManager from 'main/views/webContentEvents';
|
||||||
|
import Config from 'common/config';
|
||||||
|
|
||||||
type LoadURLOpts = {
|
type LoadURLOpts = {
|
||||||
extraHeaders: string;
|
extraHeaders: string;
|
||||||
@@ -200,6 +201,11 @@ export default class CallsWidgetWindow extends EventEmitter {
|
|||||||
|
|
||||||
private onPopOutCreate = (win: BrowserWindow) => {
|
private onPopOutCreate = (win: BrowserWindow) => {
|
||||||
this.popOut = win;
|
this.popOut = win;
|
||||||
|
|
||||||
|
// Let the webContentsEventManager handle links that try to open a new window
|
||||||
|
const spellcheck = Config.useSpellChecker;
|
||||||
|
const newWindow = webContentsEventManager.generateNewWindowListener(this.popOut.webContents.id, spellcheck);
|
||||||
|
this.popOut.webContents.setWindowOpenHandler(newWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onPopOutFocus = () => {
|
private onPopOutFocus = () => {
|
||||||
|
@@ -80,6 +80,7 @@ jest.mock('../downloadsManager', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('./callsWidgetWindow');
|
jest.mock('./callsWidgetWindow');
|
||||||
|
jest.mock('main/views/webContentEvents', () => ({}));
|
||||||
|
|
||||||
describe('main/windows/windowManager', () => {
|
describe('main/windows/windowManager', () => {
|
||||||
describe('handleUpdateConfig', () => {
|
describe('handleUpdateConfig', () => {
|
||||||
@@ -1266,6 +1267,29 @@ describe('main/windows/windowManager', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('handleCallsLinkClick', () => {
|
||||||
|
const windowManager = new WindowManager();
|
||||||
|
const view1 = {
|
||||||
|
view: {
|
||||||
|
webContents: {
|
||||||
|
send: jest.fn(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
windowManager.viewManager = {
|
||||||
|
views: new Map([
|
||||||
|
['server-1_tab-messaging', view1],
|
||||||
|
]),
|
||||||
|
getCurrentView: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
it('should pass through the click link to browser history push', () => {
|
||||||
|
windowManager.viewManager.getCurrentView.mockReturnValue(view1);
|
||||||
|
windowManager.handleCallsLinkClick(null, {link: '/other/subpath'});
|
||||||
|
expect(view1.view.webContents.send).toBeCalledWith('browser-history-push', '/other/subpath');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('getServerURLFromWebContentsId', () => {
|
describe('getServerURLFromWebContentsId', () => {
|
||||||
const view = {
|
const view = {
|
||||||
name: 'server-1_tab-messaging',
|
name: 'server-1_tab-messaging',
|
||||||
|
@@ -7,9 +7,7 @@ import path from 'path';
|
|||||||
import {app, BrowserWindow, nativeImage, systemPreferences, ipcMain, IpcMainEvent, IpcMainInvokeEvent, desktopCapturer} from 'electron';
|
import {app, BrowserWindow, nativeImage, systemPreferences, ipcMain, IpcMainEvent, IpcMainInvokeEvent, desktopCapturer} from 'electron';
|
||||||
import log from 'electron-log';
|
import log from 'electron-log';
|
||||||
|
|
||||||
import {
|
import {CallsJoinCallMessage, CallsLinkClickMessage} from 'types/calls';
|
||||||
CallsJoinCallMessage,
|
|
||||||
} from 'types/calls';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
MAXIMIZE_CHANGE,
|
MAXIMIZE_CHANGE,
|
||||||
@@ -35,6 +33,7 @@ import {
|
|||||||
DESKTOP_SOURCES_MODAL_REQUEST,
|
DESKTOP_SOURCES_MODAL_REQUEST,
|
||||||
CALLS_WIDGET_CHANNEL_LINK_CLICK,
|
CALLS_WIDGET_CHANNEL_LINK_CLICK,
|
||||||
CALLS_ERROR,
|
CALLS_ERROR,
|
||||||
|
CALLS_LINK_CLICK,
|
||||||
} from 'common/communication';
|
} from 'common/communication';
|
||||||
import urlUtils from 'common/utils/url';
|
import urlUtils from 'common/utils/url';
|
||||||
import {SECOND} from 'common/utils/constants';
|
import {SECOND} from 'common/utils/constants';
|
||||||
@@ -95,6 +94,7 @@ export class WindowManager {
|
|||||||
ipcMain.on(CALLS_LEAVE_CALL, () => this.callsWidgetWindow?.close());
|
ipcMain.on(CALLS_LEAVE_CALL, () => this.callsWidgetWindow?.close());
|
||||||
ipcMain.on(DESKTOP_SOURCES_MODAL_REQUEST, this.handleDesktopSourcesModalRequest);
|
ipcMain.on(DESKTOP_SOURCES_MODAL_REQUEST, this.handleDesktopSourcesModalRequest);
|
||||||
ipcMain.on(CALLS_WIDGET_CHANNEL_LINK_CLICK, this.handleCallsWidgetChannelLinkClick);
|
ipcMain.on(CALLS_WIDGET_CHANNEL_LINK_CLICK, this.handleCallsWidgetChannelLinkClick);
|
||||||
|
ipcMain.on(CALLS_LINK_CLICK, this.handleCallsLinkClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUpdateConfig = () => {
|
handleUpdateConfig = () => {
|
||||||
@@ -150,6 +150,13 @@ export class WindowManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleCallsLinkClick = (_: IpcMainEvent, msg: CallsLinkClickMessage) => {
|
||||||
|
log.debug('WindowManager.handleCallsLinkClick with linkURL', msg.link);
|
||||||
|
this.mainWindow?.focus();
|
||||||
|
const currentView = this.viewManager?.getCurrentView();
|
||||||
|
currentView?.view.webContents.send(BROWSER_HISTORY_PUSH, msg.link);
|
||||||
|
}
|
||||||
|
|
||||||
showSettingsWindow = () => {
|
showSettingsWindow = () => {
|
||||||
log.debug('WindowManager.showSettingsWindow');
|
log.debug('WindowManager.showSettingsWindow');
|
||||||
|
|
||||||
|
@@ -28,3 +28,7 @@ export type CallsWidgetShareScreenMessage = {
|
|||||||
export type CallsJoinedCallMessage = {
|
export type CallsJoinedCallMessage = {
|
||||||
callID: string;
|
callID: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CallsLinkClickMessage = {
|
||||||
|
link: string | URL;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user