Fix race condition on switching calls (#2591)
This commit is contained in:
@@ -75,13 +75,15 @@ describe('main/windows/callsWidgetWindow', () => {
|
|||||||
baseWindow.setAlwaysOnTop = jest.fn();
|
baseWindow.setAlwaysOnTop = jest.fn();
|
||||||
baseWindow.setBackgroundColor = jest.fn();
|
baseWindow.setBackgroundColor = jest.fn();
|
||||||
baseWindow.setMenuBarVisibility = jest.fn();
|
baseWindow.setMenuBarVisibility = jest.fn();
|
||||||
baseWindow.setBounds = jest.fn();
|
|
||||||
baseWindow.webContents = {
|
baseWindow.webContents = {
|
||||||
setWindowOpenHandler: jest.fn(),
|
setWindowOpenHandler: jest.fn(),
|
||||||
on: jest.fn(),
|
on: jest.fn(),
|
||||||
};
|
};
|
||||||
|
baseWindow.isDestroyed = jest.fn(() => false);
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
baseWindow.setBounds = jest.fn();
|
||||||
|
|
||||||
mainWindow.getBounds.mockImplementation(() => {
|
mainWindow.getBounds.mockImplementation(() => {
|
||||||
return {
|
return {
|
||||||
x: 0,
|
x: 0,
|
||||||
@@ -100,6 +102,14 @@ describe('main/windows/callsWidgetWindow', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
baseWindow.show = jest.fn(() => {
|
||||||
|
baseWindow.emit('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
baseWindow.close = jest.fn(() => {
|
||||||
|
baseWindow.emit('closed');
|
||||||
|
});
|
||||||
|
|
||||||
baseWindow.loadURL.mockImplementation(() => ({
|
baseWindow.loadURL.mockImplementation(() => ({
|
||||||
catch: jest.fn(),
|
catch: jest.fn(),
|
||||||
}));
|
}));
|
||||||
@@ -108,6 +118,8 @@ describe('main/windows/callsWidgetWindow', () => {
|
|||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.resetAllMocks();
|
jest.resetAllMocks();
|
||||||
|
baseWindow.removeAllListeners('show');
|
||||||
|
baseWindow.removeAllListeners('ready-to-show');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('verify initial configuration', () => {
|
it('verify initial configuration', () => {
|
||||||
@@ -175,14 +187,24 @@ describe('main/windows/callsWidgetWindow', () => {
|
|||||||
expect(widgetWindow.win.webContents.openDevTools).toHaveBeenCalled();
|
expect(widgetWindow.win.webContents.openDevTools).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('closing window', () => {
|
it('closing window', async () => {
|
||||||
baseWindow.close = jest.fn(() => {
|
const widgetWindow = new CallsWidgetWindow(mainWindow, mainView, widgetConfig);
|
||||||
baseWindow.emit('closed');
|
|
||||||
|
await widgetWindow.close();
|
||||||
|
|
||||||
|
expect(widgetWindow.win.close).toHaveBeenCalled();
|
||||||
|
expect(widgetWindow.win.isDestroyed).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('closing window - already closed', async () => {
|
||||||
|
baseWindow.isDestroyed = jest.fn().mockReturnValue(true);
|
||||||
|
|
||||||
const widgetWindow = new CallsWidgetWindow(mainWindow, mainView, widgetConfig);
|
const widgetWindow = new CallsWidgetWindow(mainWindow, mainView, widgetConfig);
|
||||||
widgetWindow.close();
|
|
||||||
expect(widgetWindow.win.close).toHaveBeenCalled();
|
await widgetWindow.close();
|
||||||
|
|
||||||
|
expect(widgetWindow.win.isDestroyed).toHaveBeenCalled();
|
||||||
|
expect(widgetWindow.win.close).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('resize', () => {
|
it('resize', () => {
|
||||||
@@ -191,10 +213,6 @@ describe('main/windows/callsWidgetWindow', () => {
|
|||||||
id: 'windowID',
|
id: 'windowID',
|
||||||
};
|
};
|
||||||
|
|
||||||
baseWindow.show = jest.fn(() => {
|
|
||||||
baseWindow.emit('show');
|
|
||||||
});
|
|
||||||
|
|
||||||
let winBounds = {
|
let winBounds = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
@@ -209,12 +227,18 @@ describe('main/windows/callsWidgetWindow', () => {
|
|||||||
winBounds = bounds;
|
winBounds = bounds;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
baseWindow.show = jest.fn(() => {
|
||||||
|
baseWindow.emit('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(baseWindow.setBounds).not.toHaveBeenCalled();
|
||||||
|
|
||||||
baseWindow.webContents.getZoomFactor = jest.fn(() => 1.0);
|
baseWindow.webContents.getZoomFactor = jest.fn(() => 1.0);
|
||||||
|
|
||||||
const widgetWindow = new CallsWidgetWindow(mainWindow, mainView, widgetConfig);
|
const widgetWindow = new CallsWidgetWindow(mainWindow, mainView, widgetConfig);
|
||||||
widgetWindow.win.emit('ready-to-show');
|
widgetWindow.win.emit('ready-to-show');
|
||||||
|
|
||||||
expect(baseWindow.setBounds).toHaveBeenCalledTimes(2);
|
expect(baseWindow.setBounds).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
expect(baseWindow.setBounds).toHaveBeenCalledWith({
|
expect(baseWindow.setBounds).toHaveBeenCalledWith({
|
||||||
x: 12,
|
x: 12,
|
||||||
@@ -260,10 +284,6 @@ describe('main/windows/callsWidgetWindow', () => {
|
|||||||
id: 'windowID',
|
id: 'windowID',
|
||||||
};
|
};
|
||||||
|
|
||||||
baseWindow.show = jest.fn(() => {
|
|
||||||
baseWindow.emit('show');
|
|
||||||
});
|
|
||||||
|
|
||||||
let winBounds = {
|
let winBounds = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
|
@@ -89,9 +89,16 @@ export default class CallsWidgetWindow extends EventEmitter {
|
|||||||
this.load();
|
this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
public close() {
|
public async close() {
|
||||||
log.debug('CallsWidgetWindow.close');
|
log.debug('CallsWidgetWindow.close');
|
||||||
|
return new Promise<void>((resolve) => {
|
||||||
|
if (this.win.isDestroyed()) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.once('closed', resolve);
|
||||||
this.win.close();
|
this.win.close();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public getServerName() {
|
public getServerName() {
|
||||||
|
@@ -1032,6 +1032,23 @@ describe('main/windows/windowManager', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
CallsWidgetWindow.mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
win: {
|
||||||
|
isDestroyed: jest.fn(() => true),
|
||||||
|
},
|
||||||
|
on: jest.fn(),
|
||||||
|
close: jest.fn(),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
const windowManager = new WindowManager();
|
const windowManager = new WindowManager();
|
||||||
windowManager.viewManager = {
|
windowManager.viewManager = {
|
||||||
views: new Map([
|
views: new Map([
|
||||||
@@ -1039,25 +1056,25 @@ describe('main/windows/windowManager', () => {
|
|||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
||||||
it('should create calls widget window', () => {
|
it('should create calls widget window', async () => {
|
||||||
expect(windowManager.callsWidgetWindow).toBeUndefined();
|
expect(windowManager.callsWidgetWindow).toBeUndefined();
|
||||||
windowManager.createCallsWidgetWindow('server-1_tab-messaging', {callID: 'test'});
|
await windowManager.createCallsWidgetWindow('server-1_tab-messaging', {callID: 'test'});
|
||||||
expect(windowManager.callsWidgetWindow).toBeDefined();
|
expect(windowManager.callsWidgetWindow).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not create a new window if call is the same', () => {
|
it('should not create a new window if call is the same', async () => {
|
||||||
const widgetWindow = windowManager.callsWidgetWindow;
|
const widgetWindow = windowManager.callsWidgetWindow;
|
||||||
expect(widgetWindow).toBeDefined();
|
expect(widgetWindow).toBeDefined();
|
||||||
widgetWindow.getCallID = jest.fn(() => 'test');
|
widgetWindow.getCallID = jest.fn(() => 'test');
|
||||||
windowManager.createCallsWidgetWindow('server-1_tab-messaging', {callID: 'test'});
|
await windowManager.createCallsWidgetWindow('server-1_tab-messaging', {callID: 'test'});
|
||||||
expect(windowManager.callsWidgetWindow).toEqual(widgetWindow);
|
expect(windowManager.callsWidgetWindow).toEqual(widgetWindow);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a new window if switching calls', () => {
|
it('should create a new window if switching calls', async () => {
|
||||||
const widgetWindow = windowManager.callsWidgetWindow;
|
const widgetWindow = windowManager.callsWidgetWindow;
|
||||||
expect(widgetWindow).toBeDefined();
|
expect(widgetWindow).toBeDefined();
|
||||||
widgetWindow.getCallID = jest.fn(() => 'test');
|
widgetWindow.getCallID = jest.fn(() => 'test');
|
||||||
windowManager.createCallsWidgetWindow('server-1_tab-messaging', {callID: 'test2'});
|
await windowManager.createCallsWidgetWindow('server-1_tab-messaging', {callID: 'test2'});
|
||||||
expect(windowManager.callsWidgetWindow).not.toEqual(widgetWindow);
|
expect(windowManager.callsWidgetWindow).not.toEqual(widgetWindow);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -127,14 +127,17 @@ export class WindowManager {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
createCallsWidgetWindow = (viewName: string, msg: CallsJoinCallMessage) => {
|
createCallsWidgetWindow = async (viewName: string, msg: CallsJoinCallMessage) => {
|
||||||
log.debug('WindowManager.createCallsWidgetWindow');
|
log.debug('WindowManager.createCallsWidgetWindow');
|
||||||
if (this.callsWidgetWindow) {
|
if (this.callsWidgetWindow) {
|
||||||
// trying to join again the call we are already in should not be allowed.
|
// trying to join again the call we are already in should not be allowed.
|
||||||
if (this.callsWidgetWindow.getCallID() === msg.callID) {
|
if (this.callsWidgetWindow.getCallID() === msg.callID) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.callsWidgetWindow.close();
|
|
||||||
|
// to switch from one call to another we need to wait for the existing
|
||||||
|
// window to be fully closed.
|
||||||
|
await this.callsWidgetWindow.close();
|
||||||
}
|
}
|
||||||
const currentView = this.viewManager?.views.get(viewName);
|
const currentView = this.viewManager?.views.get(viewName);
|
||||||
if (!currentView) {
|
if (!currentView) {
|
||||||
|
Reference in New Issue
Block a user