UNPKG

9.26 kBJavaScriptView Raw
1"use strict";
2// *****************************************************************************
3// Copyright (C) 2018 TypeFox and others.
4//
5// This program and the accompanying materials are made available under the
6// terms of the Eclipse Public License v. 2.0 which is available at
7// http://www.eclipse.org/legal/epl-2.0.
8//
9// This Source Code may also be made available under the following Secondary
10// Licenses when the conditions for such availability set forth in the Eclipse
11// Public License v. 2.0 are satisfied: GNU General Public License, version 2
12// with the GNU Classpath Exception which is available at
13// https://www.gnu.org/software/classpath/license.html.
14//
15// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16// *****************************************************************************
17Object.defineProperty(exports, "__esModule", { value: true });
18const jsdom_1 = require("../browser/test/jsdom");
19let disableJSDOM = (0, jsdom_1.enableJSDOM)();
20const frontend_application_config_provider_1 = require("./frontend-application-config-provider");
21frontend_application_config_provider_1.FrontendApplicationConfigProvider.set({});
22const chai_1 = require("chai");
23const connection_status_service_1 = require("./connection-status-service");
24const mock_connection_status_service_1 = require("./test/mock-connection-status-service");
25const sinon = require("sinon");
26const inversify_1 = require("inversify");
27const common_1 = require("../common");
28const ws_connection_source_1 = require("./messaging/ws-connection-source");
29disableJSDOM();
30describe('connection-status', function () {
31 let connectionStatusService;
32 before(() => {
33 disableJSDOM = (0, jsdom_1.enableJSDOM)();
34 });
35 after(() => {
36 disableJSDOM();
37 });
38 beforeEach(() => {
39 connectionStatusService = new mock_connection_status_service_1.MockConnectionStatusService();
40 });
41 afterEach(() => {
42 if (connectionStatusService !== undefined) {
43 connectionStatusService.dispose();
44 }
45 });
46 it('should go from online to offline if the connection is down', async () => {
47 (0, chai_1.expect)(connectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE);
48 connectionStatusService.alive = false;
49 await pause();
50 (0, chai_1.expect)(connectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.OFFLINE);
51 });
52 it('should go from offline to online if the connection is re-established', async () => {
53 (0, chai_1.expect)(connectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE);
54 connectionStatusService.alive = false;
55 await pause();
56 (0, chai_1.expect)(connectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.OFFLINE);
57 connectionStatusService.alive = true;
58 await pause();
59 (0, chai_1.expect)(connectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE);
60 });
61});
62describe('frontend-connection-status', function () {
63 const OFFLINE_TIMEOUT = 10;
64 let testContainer;
65 const mockSocketOpenedEmitter = new common_1.Emitter();
66 const mockSocketClosedEmitter = new common_1.Emitter();
67 const mockIncomingMessageActivityEmitter = new common_1.Emitter();
68 before(() => {
69 disableJSDOM = (0, jsdom_1.enableJSDOM)();
70 });
71 after(() => {
72 disableJSDOM();
73 });
74 let timer;
75 let pingSpy;
76 beforeEach(() => {
77 const mockWebSocketConnectionSource = sinon.createStubInstance(ws_connection_source_1.WebSocketConnectionSource);
78 const mockPingService = {
79 ping() {
80 return Promise.resolve(undefined);
81 }
82 };
83 const mockILogger = {
84 error(loggable) {
85 return Promise.resolve(undefined);
86 }
87 };
88 testContainer = new inversify_1.Container();
89 testContainer.bind(connection_status_service_1.FrontendConnectionStatusService).toSelf().inSingletonScope();
90 testContainer.bind(connection_status_service_1.PingService).toConstantValue(mockPingService);
91 testContainer.bind(common_1.ILogger).toConstantValue(mockILogger);
92 testContainer.bind(connection_status_service_1.ConnectionStatusOptions).toConstantValue({ offlineTimeout: OFFLINE_TIMEOUT });
93 testContainer.bind(ws_connection_source_1.WebSocketConnectionSource).toConstantValue(mockWebSocketConnectionSource);
94 sinon.stub(mockWebSocketConnectionSource, 'onSocketDidOpen').value(mockSocketOpenedEmitter.event);
95 sinon.stub(mockWebSocketConnectionSource, 'onSocketDidClose').value(mockSocketClosedEmitter.event);
96 sinon.stub(mockWebSocketConnectionSource, 'onIncomingMessageActivity').value(mockIncomingMessageActivityEmitter.event);
97 timer = sinon.useFakeTimers();
98 pingSpy = sinon.spy(mockPingService, 'ping');
99 });
100 afterEach(() => {
101 pingSpy.restore();
102 timer.restore();
103 testContainer.unbindAll();
104 });
105 it('should switch status to offline on websocket close', () => {
106 const frontendConnectionStatusService = testContainer.get(connection_status_service_1.FrontendConnectionStatusService);
107 frontendConnectionStatusService['init']();
108 (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE);
109 mockSocketClosedEmitter.fire(undefined);
110 (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.OFFLINE);
111 });
112 it('should switch status to online on websocket established', () => {
113 const frontendConnectionStatusService = testContainer.get(connection_status_service_1.FrontendConnectionStatusService);
114 frontendConnectionStatusService['init']();
115 mockSocketClosedEmitter.fire(undefined);
116 (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.OFFLINE);
117 mockSocketOpenedEmitter.fire(undefined);
118 (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE);
119 });
120 it('should switch status to online on any websocket activity', () => {
121 const frontendConnectionStatusService = testContainer.get(connection_status_service_1.FrontendConnectionStatusService);
122 frontendConnectionStatusService['init']();
123 mockSocketClosedEmitter.fire(undefined);
124 (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.OFFLINE);
125 mockIncomingMessageActivityEmitter.fire(undefined);
126 (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE);
127 });
128 it('should perform ping request after socket activity', () => {
129 const frontendConnectionStatusService = testContainer.get(connection_status_service_1.FrontendConnectionStatusService);
130 frontendConnectionStatusService['init']();
131 mockIncomingMessageActivityEmitter.fire(undefined);
132 (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE);
133 sinon.assert.notCalled(pingSpy);
134 timer.tick(OFFLINE_TIMEOUT);
135 sinon.assert.calledOnce(pingSpy);
136 });
137 it('should not perform ping request before desired timeout', () => {
138 const frontendConnectionStatusService = testContainer.get(connection_status_service_1.FrontendConnectionStatusService);
139 frontendConnectionStatusService['init']();
140 mockIncomingMessageActivityEmitter.fire(undefined);
141 (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE);
142 sinon.assert.notCalled(pingSpy);
143 timer.tick(OFFLINE_TIMEOUT - 1);
144 sinon.assert.notCalled(pingSpy);
145 });
146 it('should switch to offline mode if ping request was rejected', () => {
147 const pingService = testContainer.get(connection_status_service_1.PingService);
148 pingSpy.restore();
149 const stub = sinon.stub(pingService, 'ping').onFirstCall().throws('failed to make a ping request');
150 const frontendConnectionStatusService = testContainer.get(connection_status_service_1.FrontendConnectionStatusService);
151 frontendConnectionStatusService['init']();
152 mockIncomingMessageActivityEmitter.fire(undefined);
153 (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.ONLINE);
154 timer.tick(OFFLINE_TIMEOUT);
155 sinon.assert.calledOnce(stub);
156 (0, chai_1.expect)(frontendConnectionStatusService.currentStatus).to.be.equal(connection_status_service_1.ConnectionStatus.OFFLINE);
157 });
158});
159function pause(time = 1) {
160 return new Promise(resolve => setTimeout(resolve, time));
161}
162//# sourceMappingURL=connection-status-service.spec.js.map
\No newline at end of file