UNPKG

@theia/core

Version:

Theia is a cloud & desktop IDE framework implemented in TypeScript.

162 lines • 9.28 kB
"use strict"; // ***************************************************************************** // Copyright (C) 2018 TypeFox and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at // http://www.eclipse.org/legal/epl-2.0. // // This Source Code may also be made available under the following Secondary // Licenses when the conditions for such availability set forth in the Eclipse // Public License v. 2.0 are satisfied: GNU General Public License, version 2 // with the GNU Classpath Exception which is available at // https://www.gnu.org/software/classpath/license.html. // // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** Object.defineProperty(exports, "__esModule", { value: true }); const jsdom_1 = require("../browser/test/jsdom"); let disableJSDOM = (0, jsdom_1.enableJSDOM)(); const frontend_application_config_provider_1 = require("./frontend-application-config-provider"); frontend_application_config_provider_1.FrontendApplicationConfigProvider.set({}); const chai_1 = require("chai"); const connection_status_service_1 = require("./connection-status-service"); const mock_connection_status_service_1 = require("./test/mock-connection-status-service"); const sinon = require("sinon"); const inversify_1 = require("inversify"); const ws_connection_provider_1 = require("./messaging/ws-connection-provider"); const common_1 = require("../common"); disableJSDOM(); describe('connection-status', function () { let connectionStatusService; before(() => { disableJSDOM = (0, jsdom_1.enableJSDOM)(); }); after(() => { disableJSDOM(); }); beforeEach(() => { connectionStatusService = new mock_connection_status_service_1.MockConnectionStatusService(); }); afterEach(() => { if (connectionStatusService !== undefined) { connectionStatusService.dispose(); } }); it('should go from online to offline if the connection is down', async () => { (0, chai_1.expect)(connectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE); connectionStatusService.alive = false; await pause(); (0, chai_1.expect)(connectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.OFFLINE); }); it('should go from offline to online if the connection is re-established', async () => { (0, chai_1.expect)(connectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE); connectionStatusService.alive = false; await pause(); (0, chai_1.expect)(connectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.OFFLINE); connectionStatusService.alive = true; await pause(); (0, chai_1.expect)(connectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE); }); }); describe('frontend-connection-status', function () { const OFFLINE_TIMEOUT = 10; let testContainer; const mockSocketOpenedEmitter = new common_1.Emitter(); const mockSocketClosedEmitter = new common_1.Emitter(); const mockIncomingMessageActivityEmitter = new common_1.Emitter(); before(() => { disableJSDOM = (0, jsdom_1.enableJSDOM)(); }); after(() => { disableJSDOM(); }); let timer; let pingSpy; beforeEach(() => { const mockWebSocketConnectionProvider = sinon.createStubInstance(ws_connection_provider_1.WebSocketConnectionProvider); const mockPingService = { ping() { return Promise.resolve(undefined); } }; const mockILogger = { error(loggable) { return Promise.resolve(undefined); } }; testContainer = new inversify_1.Container(); testContainer.bind(connection_status_service_1.FrontendConnectionStatusService).toSelf().inSingletonScope(); testContainer.bind(connection_status_service_1.PingService).toConstantValue(mockPingService); testContainer.bind(common_1.ILogger).toConstantValue(mockILogger); testContainer.bind(connection_status_service_1.ConnectionStatusOptions).toConstantValue({ offlineTimeout: OFFLINE_TIMEOUT }); testContainer.bind(ws_connection_provider_1.WebSocketConnectionProvider).toConstantValue(mockWebSocketConnectionProvider); sinon.stub(mockWebSocketConnectionProvider, 'onSocketDidOpen').value(mockSocketOpenedEmitter.event); sinon.stub(mockWebSocketConnectionProvider, 'onSocketDidClose').value(mockSocketClosedEmitter.event); sinon.stub(mockWebSocketConnectionProvider, 'onIncomingMessageActivity').value(mockIncomingMessageActivityEmitter.event); timer = sinon.useFakeTimers(); pingSpy = sinon.spy(mockPingService, 'ping'); }); afterEach(() => { pingSpy.restore(); timer.restore(); testContainer.unbindAll(); }); it('should switch status to offline on websocket close', () => { const frontendConnectionStatusService = testContainer.get(connection_status_service_1.FrontendConnectionStatusService); frontendConnectionStatusService['init'](); (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE); mockSocketClosedEmitter.fire(undefined); (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.OFFLINE); }); it('should switch status to online on websocket established', () => { const frontendConnectionStatusService = testContainer.get(connection_status_service_1.FrontendConnectionStatusService); frontendConnectionStatusService['init'](); mockSocketClosedEmitter.fire(undefined); (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.OFFLINE); mockSocketOpenedEmitter.fire(undefined); (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE); }); it('should switch status to online on any websocket activity', () => { const frontendConnectionStatusService = testContainer.get(connection_status_service_1.FrontendConnectionStatusService); frontendConnectionStatusService['init'](); mockSocketClosedEmitter.fire(undefined); (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.OFFLINE); mockIncomingMessageActivityEmitter.fire(undefined); (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE); }); it('should perform ping request after socket activity', () => { const frontendConnectionStatusService = testContainer.get(connection_status_service_1.FrontendConnectionStatusService); frontendConnectionStatusService['init'](); mockIncomingMessageActivityEmitter.fire(undefined); (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE); sinon.assert.notCalled(pingSpy); timer.tick(OFFLINE_TIMEOUT); sinon.assert.calledOnce(pingSpy); }); it('should not perform ping request before desired timeout', () => { const frontendConnectionStatusService = testContainer.get(connection_status_service_1.FrontendConnectionStatusService); frontendConnectionStatusService['init'](); mockIncomingMessageActivityEmitter.fire(undefined); (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE); sinon.assert.notCalled(pingSpy); timer.tick(OFFLINE_TIMEOUT - 1); sinon.assert.notCalled(pingSpy); }); it('should switch to offline mode if ping request was rejected', () => { const pingService = testContainer.get(connection_status_service_1.PingService); pingSpy.restore(); const stub = sinon.stub(pingService, 'ping').onFirstCall().throws('failed to make a ping request'); const frontendConnectionStatusService = testContainer.get(connection_status_service_1.FrontendConnectionStatusService); frontendConnectionStatusService['init'](); mockIncomingMessageActivityEmitter.fire(undefined); (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE); timer.tick(OFFLINE_TIMEOUT); sinon.assert.calledOnce(stub); (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.OFFLINE); }); }); function pause(time = 1) { return new Promise(resolve => setTimeout(resolve, time)); } //# sourceMappingURL=connection-status-service.spec.js.map