@webex/plugin-meetings 3.3.1-next.2 → 3.3.1-next.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +7 -2
- package/dist/breakouts/index.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/media/MediaConnectionAwaiter.js +50 -13
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js +16 -6
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/connectionStateHandler.js +67 -0
- package/dist/meeting/connectionStateHandler.js.map +1 -0
- package/dist/meeting/index.js +98 -46
- package/dist/meeting/index.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +57 -0
- package/dist/metrics/index.js.map +1 -1
- package/dist/reachability/clusterReachability.js +108 -53
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +415 -56
- package/dist/reachability/index.js.map +1 -1
- package/dist/statsAnalyzer/index.js +81 -27
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +36 -10
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/media/MediaConnectionAwaiter.d.ts +18 -4
- package/dist/types/mediaQualityMetrics/config.d.ts +11 -0
- package/dist/types/meeting/connectionStateHandler.d.ts +30 -0
- package/dist/types/meeting/index.d.ts +2 -0
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/metrics/index.d.ts +15 -0
- package/dist/types/reachability/clusterReachability.d.ts +31 -3
- package/dist/types/reachability/index.d.ts +93 -2
- package/dist/types/statsAnalyzer/index.d.ts +15 -6
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +17 -4
- package/dist/webinar/index.js +1 -1
- package/package.json +23 -22
- package/src/breakouts/index.ts +7 -1
- package/src/media/MediaConnectionAwaiter.ts +66 -11
- package/src/mediaQualityMetrics/config.ts +14 -3
- package/src/meeting/connectionStateHandler.ts +65 -0
- package/src/meeting/index.ts +72 -14
- package/src/metrics/constants.ts +1 -0
- package/src/metrics/index.ts +44 -0
- package/src/reachability/clusterReachability.ts +86 -25
- package/src/reachability/index.ts +316 -27
- package/src/statsAnalyzer/index.ts +85 -24
- package/src/statsAnalyzer/mqaUtil.ts +55 -7
- package/test/unit/spec/breakouts/index.ts +51 -32
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +90 -32
- package/test/unit/spec/meeting/connectionStateHandler.ts +102 -0
- package/test/unit/spec/meeting/index.js +158 -36
- package/test/unit/spec/metrics/index.js +126 -0
- package/test/unit/spec/reachability/clusterReachability.ts +116 -22
- package/test/unit/spec/reachability/index.ts +1153 -84
- package/test/unit/spec/stats-analyzer/index.js +647 -319
|
@@ -19,6 +19,8 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
19
19
|
off: sinon.stub(),
|
|
20
20
|
getConnectionState: sinon.stub().returns(ConnectionState.New),
|
|
21
21
|
getIceGatheringState: sinon.stub().returns('new'),
|
|
22
|
+
getIceConnectionState: sinon.stub().returns('new'),
|
|
23
|
+
getPeerConnectionState: sinon.stub().returns('new'),
|
|
22
24
|
};
|
|
23
25
|
|
|
24
26
|
mediaConnectionAwaiter = new MediaConnectionAwaiter({
|
|
@@ -52,8 +54,11 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
52
54
|
.then(() => {
|
|
53
55
|
promiseResolved = true;
|
|
54
56
|
})
|
|
55
|
-
.catch(() => {
|
|
57
|
+
.catch((error) => {
|
|
56
58
|
promiseRejected = true;
|
|
59
|
+
|
|
60
|
+
const {iceConnected} = error;
|
|
61
|
+
assert.equal(iceConnected, false);
|
|
57
62
|
});
|
|
58
63
|
|
|
59
64
|
await testUtils.flushPromises();
|
|
@@ -61,21 +66,68 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
61
66
|
assert.equal(promiseRejected, false);
|
|
62
67
|
|
|
63
68
|
// check the right listener was registered
|
|
64
|
-
assert.
|
|
65
|
-
assert.equal(mockMC.on.getCall(0).args[0], Event.
|
|
66
|
-
assert.equal(mockMC.on.getCall(1).args[0], Event.
|
|
67
|
-
|
|
69
|
+
assert.calledThrice(mockMC.on);
|
|
70
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
71
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
72
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
73
|
+
const iceGatheringListener = mockMC.on.getCall(2).args[1];
|
|
68
74
|
|
|
75
|
+
mockMC.getIceGatheringState.returns('complete');
|
|
76
|
+
iceGatheringListener();
|
|
77
|
+
|
|
78
|
+
await clock.tickAsync(ICE_AND_DTLS_CONNECTION_TIMEOUT);
|
|
79
|
+
await testUtils.flushPromises();
|
|
80
|
+
|
|
81
|
+
assert.equal(promiseResolved, false);
|
|
82
|
+
assert.equal(promiseRejected, true);
|
|
83
|
+
|
|
84
|
+
assert.calledThrice(mockMC.off);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('rejects after timeout if dtls state is not connected', async () => {
|
|
88
|
+
mockMC.getConnectionState.returns(ConnectionState.Connecting);
|
|
89
|
+
mockMC.getIceGatheringState.returns('gathering');
|
|
90
|
+
|
|
91
|
+
let promiseResolved = false;
|
|
92
|
+
let promiseRejected = false;
|
|
93
|
+
|
|
94
|
+
mediaConnectionAwaiter
|
|
95
|
+
.waitForMediaConnectionConnected()
|
|
96
|
+
.then(() => {
|
|
97
|
+
promiseResolved = true;
|
|
98
|
+
})
|
|
99
|
+
.catch((error) => {
|
|
100
|
+
promiseRejected = true;
|
|
101
|
+
|
|
102
|
+
const {iceConnected} = error;
|
|
103
|
+
assert.equal(iceConnected, false);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
await testUtils.flushPromises();
|
|
107
|
+
assert.equal(promiseResolved, false);
|
|
108
|
+
assert.equal(promiseRejected, false);
|
|
109
|
+
|
|
110
|
+
// check the right listener was registered
|
|
111
|
+
assert.calledThrice(mockMC.on);
|
|
112
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
113
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
114
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
115
|
+
const listener = mockMC.on.getCall(1).args[1];
|
|
116
|
+
const iceConnectionListener = mockMC.on.getCall(1).args[1];
|
|
117
|
+
|
|
69
118
|
mockMC.getIceGatheringState.returns('complete');
|
|
70
119
|
listener();
|
|
71
120
|
|
|
121
|
+
mockMC.getIceConnectionState.returns('connected');
|
|
122
|
+
iceConnectionListener();
|
|
123
|
+
|
|
72
124
|
await clock.tickAsync(ICE_AND_DTLS_CONNECTION_TIMEOUT);
|
|
73
125
|
await testUtils.flushPromises();
|
|
74
126
|
|
|
75
127
|
assert.equal(promiseResolved, false);
|
|
76
128
|
assert.equal(promiseRejected, true);
|
|
77
129
|
|
|
78
|
-
assert.
|
|
130
|
+
assert.calledThrice(mockMC.off);
|
|
79
131
|
});
|
|
80
132
|
|
|
81
133
|
it('resolves after timeout if connection state reach connected/completed', async () => {
|
|
@@ -99,9 +151,10 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
99
151
|
assert.equal(promiseRejected, false);
|
|
100
152
|
|
|
101
153
|
// check the right listener was registered
|
|
102
|
-
assert.
|
|
103
|
-
assert.equal(mockMC.on.getCall(0).args[0], Event.
|
|
104
|
-
assert.equal(mockMC.on.getCall(1).args[0], Event.
|
|
154
|
+
assert.calledThrice(mockMC.on);
|
|
155
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
156
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
157
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
105
158
|
|
|
106
159
|
mockMC.getConnectionState.returns(ConnectionState.Connected);
|
|
107
160
|
|
|
@@ -111,7 +164,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
111
164
|
assert.equal(promiseResolved, true);
|
|
112
165
|
assert.equal(promiseRejected, false);
|
|
113
166
|
|
|
114
|
-
assert.
|
|
167
|
+
assert.calledThrice(mockMC.off);
|
|
115
168
|
});
|
|
116
169
|
|
|
117
170
|
it(`resolves when media connection reaches "connected" state`, async () => {
|
|
@@ -137,9 +190,10 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
137
190
|
assert.equal(promiseRejected, false);
|
|
138
191
|
|
|
139
192
|
// check the right listener was registered
|
|
140
|
-
assert.
|
|
141
|
-
assert.equal(mockMC.on.getCall(0).args[0], Event.
|
|
142
|
-
assert.equal(mockMC.on.getCall(1).args[0], Event.
|
|
193
|
+
assert.calledThrice(mockMC.on);
|
|
194
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
195
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
196
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
143
197
|
const listener = mockMC.on.getCall(0).args[1];
|
|
144
198
|
|
|
145
199
|
// call the listener and pretend we are now connected
|
|
@@ -151,7 +205,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
151
205
|
assert.equal(promiseRejected, false);
|
|
152
206
|
|
|
153
207
|
// check that listener was removed
|
|
154
|
-
assert.
|
|
208
|
+
assert.calledThrice(mockMC.off);
|
|
155
209
|
|
|
156
210
|
assert.calledOnce(clearTimeoutSpy);
|
|
157
211
|
});
|
|
@@ -179,9 +233,10 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
179
233
|
assert.equal(promiseRejected, false);
|
|
180
234
|
|
|
181
235
|
// check the right listener was registered
|
|
182
|
-
assert.
|
|
183
|
-
assert.equal(mockMC.on.getCall(0).args[0], Event.
|
|
184
|
-
assert.equal(mockMC.on.getCall(1).args[0], Event.
|
|
236
|
+
assert.calledThrice(mockMC.on);
|
|
237
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
238
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
239
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
185
240
|
const listener = mockMC.on.getCall(1).args[1];
|
|
186
241
|
|
|
187
242
|
// call the listener and pretend we are now connected
|
|
@@ -197,7 +252,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
197
252
|
assert.equal(promiseRejected, false);
|
|
198
253
|
|
|
199
254
|
// check that listener was removed
|
|
200
|
-
assert.
|
|
255
|
+
assert.calledThrice(mockMC.off);
|
|
201
256
|
|
|
202
257
|
assert.neverCalledWith(clearTimeoutSpy);
|
|
203
258
|
});
|
|
@@ -228,10 +283,11 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
228
283
|
assert.calledOnce(setTimeoutSpy);
|
|
229
284
|
|
|
230
285
|
// check the right listener was registered
|
|
231
|
-
assert.
|
|
232
|
-
assert.equal(mockMC.on.getCall(0).args[0], Event.
|
|
233
|
-
assert.equal(mockMC.on.getCall(1).args[0], Event.
|
|
234
|
-
|
|
286
|
+
assert.calledThrice(mockMC.on);
|
|
287
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
288
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
289
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
290
|
+
const listener = mockMC.on.getCall(2).args[1];
|
|
235
291
|
|
|
236
292
|
// call the listener and pretend we are now connected
|
|
237
293
|
mockMC.getIceGatheringState.returns('complete');
|
|
@@ -249,7 +305,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
249
305
|
assert.equal(promiseRejected, false);
|
|
250
306
|
|
|
251
307
|
// check that listener was removed
|
|
252
|
-
assert.
|
|
308
|
+
assert.calledThrice(mockMC.off);
|
|
253
309
|
});
|
|
254
310
|
|
|
255
311
|
it(`reject with restart timer once if gathering state is not complete`, async () => {
|
|
@@ -276,9 +332,10 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
276
332
|
assert.equal(promiseRejected, false);
|
|
277
333
|
|
|
278
334
|
// check the right listener was registered
|
|
279
|
-
assert.
|
|
280
|
-
assert.equal(mockMC.on.getCall(0).args[0], Event.
|
|
281
|
-
assert.equal(mockMC.on.getCall(1).args[0], Event.
|
|
335
|
+
assert.calledThrice(mockMC.on);
|
|
336
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
337
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
338
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
282
339
|
|
|
283
340
|
await clock.tickAsync(ICE_AND_DTLS_CONNECTION_TIMEOUT * 2);
|
|
284
341
|
await testUtils.flushPromises();
|
|
@@ -287,7 +344,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
287
344
|
assert.equal(promiseRejected, true);
|
|
288
345
|
|
|
289
346
|
// check that listener was removed
|
|
290
|
-
assert.
|
|
347
|
+
assert.calledThrice(mockMC.off);
|
|
291
348
|
|
|
292
349
|
assert.calledOnce(clearTimeoutSpy);
|
|
293
350
|
assert.calledTwice(setTimeoutSpy);
|
|
@@ -317,11 +374,12 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
317
374
|
assert.equal(promiseRejected, false);
|
|
318
375
|
|
|
319
376
|
// check the right listener was registered
|
|
320
|
-
assert.
|
|
321
|
-
assert.equal(mockMC.on.getCall(0).args[0], Event.
|
|
322
|
-
assert.equal(mockMC.on.getCall(1).args[0], Event.
|
|
377
|
+
assert.calledThrice(mockMC.on);
|
|
378
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
379
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
380
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
323
381
|
const connectionStateListener = mockMC.on.getCall(0).args[1];
|
|
324
|
-
const iceGatheringListener = mockMC.on.getCall(
|
|
382
|
+
const iceGatheringListener = mockMC.on.getCall(2).args[1];
|
|
325
383
|
|
|
326
384
|
mockMC.getIceGatheringState.returns('complete');
|
|
327
385
|
iceGatheringListener();
|
|
@@ -335,7 +393,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
335
393
|
assert.equal(promiseRejected, false);
|
|
336
394
|
|
|
337
395
|
// check that listener was removed
|
|
338
|
-
assert.
|
|
396
|
+
assert.calledThrice(mockMC.off);
|
|
339
397
|
|
|
340
398
|
assert.calledTwice(clearTimeoutSpy);
|
|
341
399
|
assert.calledTwice(setTimeoutSpy);
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import sinon from 'sinon';
|
|
2
|
+
import {assert} from '@webex/test-helper-chai';
|
|
3
|
+
import {
|
|
4
|
+
ConnectionStateHandler,
|
|
5
|
+
ConnectionStateEvent,
|
|
6
|
+
} from '@webex/plugin-meetings/src/meeting/connectionStateHandler';
|
|
7
|
+
import {Event, ConnectionState} from '@webex/internal-media-core';
|
|
8
|
+
|
|
9
|
+
describe('ConnectionStateHandler', () => {
|
|
10
|
+
let connectionStateHandler: ConnectionStateHandler;
|
|
11
|
+
let mockMC;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
mockMC = {
|
|
15
|
+
on: sinon.stub(),
|
|
16
|
+
off: sinon.stub(),
|
|
17
|
+
getConnectionState: sinon.stub().returns(ConnectionState.Connecting),
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
connectionStateHandler = new ConnectionStateHandler(mockMC);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('ConnectionStateChangedEvent', () => {
|
|
24
|
+
it('should emit a stateChanged event when the peer connection state changes', () => {
|
|
25
|
+
const spy = sinon.spy(connectionStateHandler, 'emit');
|
|
26
|
+
|
|
27
|
+
// check the right listener was registered
|
|
28
|
+
assert.calledTwice(mockMC.on);
|
|
29
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
30
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
31
|
+
const listener = mockMC.on.getCall(0).args[1];
|
|
32
|
+
|
|
33
|
+
listener();
|
|
34
|
+
|
|
35
|
+
assert.calledOnce(spy);
|
|
36
|
+
assert.calledOnceWithExactly(
|
|
37
|
+
connectionStateHandler.emit,
|
|
38
|
+
{
|
|
39
|
+
file: 'connectionStateHandler',
|
|
40
|
+
function: 'handleConnectionStateChange',
|
|
41
|
+
},
|
|
42
|
+
ConnectionStateEvent.stateChanged,
|
|
43
|
+
{
|
|
44
|
+
state: ConnectionState.Connecting,
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should emit a stateChanged event when the ice connection state changes', () => {
|
|
50
|
+
const spy = sinon.spy(connectionStateHandler, 'emit');
|
|
51
|
+
|
|
52
|
+
// check the right listener was registered
|
|
53
|
+
assert.calledTwice(mockMC.on);
|
|
54
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
55
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
56
|
+
const listener = mockMC.on.getCall(1).args[1];
|
|
57
|
+
|
|
58
|
+
listener();
|
|
59
|
+
|
|
60
|
+
assert.calledOnce(spy);
|
|
61
|
+
assert.calledOnceWithExactly(
|
|
62
|
+
connectionStateHandler.emit,
|
|
63
|
+
{
|
|
64
|
+
file: 'connectionStateHandler',
|
|
65
|
+
function: 'handleConnectionStateChange',
|
|
66
|
+
},
|
|
67
|
+
ConnectionStateEvent.stateChanged,
|
|
68
|
+
{
|
|
69
|
+
state: ConnectionState.Connecting,
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should emit a stateChanged event only once when overall connection state does not change', () => {
|
|
75
|
+
const spy = sinon.spy(connectionStateHandler, 'emit');
|
|
76
|
+
|
|
77
|
+
// check the right listener was registered
|
|
78
|
+
assert.calledTwice(mockMC.on);
|
|
79
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
80
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
81
|
+
const peerConnectionListener = mockMC.on.getCall(0).args[1];
|
|
82
|
+
const iceConnectionListener = mockMC.on.getCall(1).args[1];
|
|
83
|
+
|
|
84
|
+
peerConnectionListener();
|
|
85
|
+
|
|
86
|
+
iceConnectionListener();
|
|
87
|
+
|
|
88
|
+
assert.calledOnce(spy);
|
|
89
|
+
assert.calledOnceWithExactly(
|
|
90
|
+
connectionStateHandler.emit,
|
|
91
|
+
{
|
|
92
|
+
file: 'connectionStateHandler',
|
|
93
|
+
function: 'handleConnectionStateChange',
|
|
94
|
+
},
|
|
95
|
+
ConnectionStateEvent.stateChanged,
|
|
96
|
+
{
|
|
97
|
+
state: ConnectionState.Connecting,
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
});
|