1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | Object.defineProperty(exports, "__esModule", { value: true });
|
18 | const jsdom_1 = require("../browser/test/jsdom");
|
19 | let disableJSDOM = (0, jsdom_1.enableJSDOM)();
|
20 | const frontend_application_config_provider_1 = require("./frontend-application-config-provider");
|
21 | frontend_application_config_provider_1.FrontendApplicationConfigProvider.set({});
|
22 | const chai_1 = require("chai");
|
23 | const connection_status_service_1 = require("./connection-status-service");
|
24 | const mock_connection_status_service_1 = require("./test/mock-connection-status-service");
|
25 | const sinon = require("sinon");
|
26 | const inversify_1 = require("inversify");
|
27 | const ws_connection_provider_1 = require("./messaging/ws-connection-provider");
|
28 | const common_1 = require("../common");
|
29 | disableJSDOM();
|
30 | describe('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 | });
|
62 | describe('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 mockWebSocketConnectionProvider = sinon.createStubInstance(ws_connection_provider_1.WebSocketConnectionProvider);
|
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_provider_1.WebSocketConnectionProvider).toConstantValue(mockWebSocketConnectionProvider);
|
94 | sinon.stub(mockWebSocketConnectionProvider, 'onSocketDidOpen').value(mockSocketOpenedEmitter.event);
|
95 | sinon.stub(mockWebSocketConnectionProvider, 'onSocketDidClose').value(mockSocketClosedEmitter.event);
|
96 | sinon.stub(mockWebSocketConnectionProvider, '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 | });
|
159 | function pause(time = 1) {
|
160 | return new Promise(resolve => setTimeout(resolve, time));
|
161 | }
|
162 |
|
\ | No newline at end of file |