@webex/plugin-meetings 3.3.1 → 3.4.0
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/constants.js +11 -4
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/selfUtils.js +0 -5
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +70 -15
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/index.js +12 -0
- package/dist/media/index.js.map +1 -1
- package/dist/meeting/connectionStateHandler.js +67 -0
- package/dist/meeting/connectionStateHandler.js.map +1 -0
- package/dist/meeting/index.js +552 -357
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +7 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/muteState.js +6 -1
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/util.js +1 -0
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +4 -4
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +2 -2
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/util.js +17 -17
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +16 -16
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +1 -1
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +37 -33
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +8 -0
- package/dist/meetings/meetings.types.js.map +1 -1
- package/dist/meetings/util.js +3 -2
- package/dist/meetings/util.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/personal-meeting-room/index.js +1 -1
- package/dist/personal-meeting-room/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/types/constants.d.ts +11 -3
- package/dist/types/media/MediaConnectionAwaiter.d.ts +24 -4
- package/dist/types/meeting/connectionStateHandler.d.ts +30 -0
- package/dist/types/meeting/index.d.ts +27 -7
- package/dist/types/meeting/locusMediaRequest.d.ts +2 -0
- package/dist/types/meeting-info/index.d.ts +3 -2
- package/dist/types/meeting-info/meeting-info-v2.d.ts +3 -2
- package/dist/types/meeting-info/util.d.ts +5 -4
- package/dist/types/meeting-info/utilv2.d.ts +3 -2
- package/dist/types/meetings/collection.d.ts +3 -2
- package/dist/types/meetings/index.d.ts +4 -3
- package/dist/types/meetings/meetings.types.d.ts +9 -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/webinar/index.js +1 -1
- package/package.json +23 -23
- package/src/breakouts/index.ts +7 -1
- package/src/constants.ts +13 -17
- package/src/locus-info/selfUtils.ts +0 -5
- package/src/media/MediaConnectionAwaiter.ts +89 -14
- package/src/media/index.ts +13 -0
- package/src/meeting/connectionStateHandler.ts +65 -0
- package/src/meeting/index.ts +526 -292
- package/src/meeting/locusMediaRequest.ts +5 -0
- package/src/meeting/muteState.ts +6 -1
- package/src/meeting/util.ts +1 -0
- package/src/meeting-info/index.ts +9 -6
- package/src/meeting-info/meeting-info-v2.ts +4 -4
- package/src/meeting-info/util.ts +23 -28
- package/src/meeting-info/utilv2.ts +18 -24
- package/src/meetings/collection.ts +3 -3
- package/src/meetings/index.ts +39 -40
- package/src/meetings/meetings.types.ts +11 -0
- package/src/meetings/util.ts +5 -4
- package/src/metrics/constants.ts +1 -0
- package/src/metrics/index.ts +44 -0
- package/src/personal-meeting-room/index.ts +2 -2
- package/src/reachability/clusterReachability.ts +86 -25
- package/src/reachability/index.ts +316 -27
- package/test/unit/spec/breakouts/index.ts +51 -32
- package/test/unit/spec/locus-info/selfUtils.js +25 -23
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +131 -32
- package/test/unit/spec/media/index.ts +42 -27
- package/test/unit/spec/meeting/connectionStateHandler.ts +102 -0
- package/test/unit/spec/meeting/index.js +758 -179
- package/test/unit/spec/meeting/locusMediaRequest.ts +7 -0
- package/test/unit/spec/meeting/muteState.js +24 -0
- package/test/unit/spec/meeting-info/index.js +4 -4
- package/test/unit/spec/meeting-info/meetinginfov2.js +24 -28
- package/test/unit/spec/meeting-info/request.js +2 -2
- package/test/unit/spec/meeting-info/utilv2.js +41 -49
- package/test/unit/spec/meetings/index.js +14 -0
- package/test/unit/spec/metrics/index.js +126 -0
- package/test/unit/spec/multistream/mediaRequestManager.ts +2 -2
- package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -2
- package/test/unit/spec/reachability/clusterReachability.ts +116 -22
- package/test/unit/spec/reachability/index.ts +1153 -84
- package/test/unit/spec/rtcMetrics/index.ts +1 -0
- package/dist/mediaQualityMetrics/config.js +0 -321
- package/dist/mediaQualityMetrics/config.js.map +0 -1
- package/dist/statsAnalyzer/global.js +0 -44
- package/dist/statsAnalyzer/global.js.map +0 -1
- package/dist/statsAnalyzer/index.js +0 -1072
- package/dist/statsAnalyzer/index.js.map +0 -1
- package/dist/statsAnalyzer/mqaUtil.js +0 -368
- package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
- package/dist/types/mediaQualityMetrics/config.d.ts +0 -247
- package/dist/types/statsAnalyzer/global.d.ts +0 -36
- package/dist/types/statsAnalyzer/index.d.ts +0 -217
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
- package/src/mediaQualityMetrics/config.ts +0 -255
- package/src/statsAnalyzer/global.ts +0 -37
- package/src/statsAnalyzer/index.ts +0 -1318
- package/src/statsAnalyzer/mqaUtil.ts +0 -463
- package/test/unit/spec/stats-analyzer/index.js +0 -1819
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {assert} from '@webex/test-helper-chai';
|
|
2
2
|
import sinon from 'sinon';
|
|
3
|
-
import {ConnectionState,
|
|
3
|
+
import {ConnectionState, MediaConnectionEventNames} from '@webex/internal-media-core';
|
|
4
4
|
import testUtils from '../../../utils/testUtils';
|
|
5
5
|
import {ICE_AND_DTLS_CONNECTION_TIMEOUT} from '@webex/plugin-meetings/src/constants';
|
|
6
6
|
import MediaConnectionAwaiter from '../../../../src/media/MediaConnectionAwaiter';
|
|
@@ -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,109 @@ 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],
|
|
66
|
-
assert.equal(mockMC.on.getCall(1).args[0],
|
|
69
|
+
assert.calledThrice(mockMC.on);
|
|
70
|
+
assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
|
|
71
|
+
assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
|
|
72
|
+
assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
|
|
73
|
+
const iceGatheringListener = mockMC.on.getCall(2).args[1];
|
|
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 immediately if ice state is FAILED', 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], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
|
|
113
|
+
assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
|
|
114
|
+
assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
|
|
115
|
+
const iceConnectionListener = mockMC.on.getCall(1).args[1];
|
|
116
|
+
|
|
117
|
+
mockMC.getConnectionState.returns(ConnectionState.Failed);
|
|
118
|
+
iceConnectionListener();
|
|
119
|
+
|
|
120
|
+
await testUtils.flushPromises();
|
|
121
|
+
|
|
122
|
+
assert.equal(promiseResolved, false);
|
|
123
|
+
assert.equal(promiseRejected, true);
|
|
124
|
+
|
|
125
|
+
assert.calledThrice(mockMC.off);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('rejects after timeout if dtls state is not connected', async () => {
|
|
129
|
+
mockMC.getConnectionState.returns(ConnectionState.Connecting);
|
|
130
|
+
mockMC.getIceGatheringState.returns('gathering');
|
|
131
|
+
|
|
132
|
+
let promiseResolved = false;
|
|
133
|
+
let promiseRejected = false;
|
|
134
|
+
|
|
135
|
+
mediaConnectionAwaiter
|
|
136
|
+
.waitForMediaConnectionConnected()
|
|
137
|
+
.then(() => {
|
|
138
|
+
promiseResolved = true;
|
|
139
|
+
})
|
|
140
|
+
.catch((error) => {
|
|
141
|
+
promiseRejected = true;
|
|
142
|
+
|
|
143
|
+
const {iceConnected} = error;
|
|
144
|
+
assert.equal(iceConnected, false);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
await testUtils.flushPromises();
|
|
148
|
+
assert.equal(promiseResolved, false);
|
|
149
|
+
assert.equal(promiseRejected, false);
|
|
150
|
+
|
|
151
|
+
// check the right listener was registered
|
|
152
|
+
assert.calledThrice(mockMC.on);
|
|
153
|
+
assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
|
|
154
|
+
assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
|
|
155
|
+
assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
|
|
67
156
|
const listener = mockMC.on.getCall(1).args[1];
|
|
157
|
+
const iceConnectionListener = mockMC.on.getCall(1).args[1];
|
|
68
158
|
|
|
69
159
|
mockMC.getIceGatheringState.returns('complete');
|
|
70
160
|
listener();
|
|
71
161
|
|
|
162
|
+
mockMC.getIceConnectionState.returns('connected');
|
|
163
|
+
iceConnectionListener();
|
|
164
|
+
|
|
72
165
|
await clock.tickAsync(ICE_AND_DTLS_CONNECTION_TIMEOUT);
|
|
73
166
|
await testUtils.flushPromises();
|
|
74
167
|
|
|
75
168
|
assert.equal(promiseResolved, false);
|
|
76
169
|
assert.equal(promiseRejected, true);
|
|
77
170
|
|
|
78
|
-
assert.
|
|
171
|
+
assert.calledThrice(mockMC.off);
|
|
79
172
|
});
|
|
80
173
|
|
|
81
174
|
it('resolves after timeout if connection state reach connected/completed', async () => {
|
|
@@ -99,9 +192,10 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
99
192
|
assert.equal(promiseRejected, false);
|
|
100
193
|
|
|
101
194
|
// check the right listener was registered
|
|
102
|
-
assert.
|
|
103
|
-
assert.equal(mockMC.on.getCall(0).args[0],
|
|
104
|
-
assert.equal(mockMC.on.getCall(1).args[0],
|
|
195
|
+
assert.calledThrice(mockMC.on);
|
|
196
|
+
assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
|
|
197
|
+
assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
|
|
198
|
+
assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
|
|
105
199
|
|
|
106
200
|
mockMC.getConnectionState.returns(ConnectionState.Connected);
|
|
107
201
|
|
|
@@ -111,7 +205,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
111
205
|
assert.equal(promiseResolved, true);
|
|
112
206
|
assert.equal(promiseRejected, false);
|
|
113
207
|
|
|
114
|
-
assert.
|
|
208
|
+
assert.calledThrice(mockMC.off);
|
|
115
209
|
});
|
|
116
210
|
|
|
117
211
|
it(`resolves when media connection reaches "connected" state`, async () => {
|
|
@@ -137,9 +231,10 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
137
231
|
assert.equal(promiseRejected, false);
|
|
138
232
|
|
|
139
233
|
// check the right listener was registered
|
|
140
|
-
assert.
|
|
141
|
-
assert.equal(mockMC.on.getCall(0).args[0],
|
|
142
|
-
assert.equal(mockMC.on.getCall(1).args[0],
|
|
234
|
+
assert.calledThrice(mockMC.on);
|
|
235
|
+
assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
|
|
236
|
+
assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
|
|
237
|
+
assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
|
|
143
238
|
const listener = mockMC.on.getCall(0).args[1];
|
|
144
239
|
|
|
145
240
|
// call the listener and pretend we are now connected
|
|
@@ -151,7 +246,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
151
246
|
assert.equal(promiseRejected, false);
|
|
152
247
|
|
|
153
248
|
// check that listener was removed
|
|
154
|
-
assert.
|
|
249
|
+
assert.calledThrice(mockMC.off);
|
|
155
250
|
|
|
156
251
|
assert.calledOnce(clearTimeoutSpy);
|
|
157
252
|
});
|
|
@@ -179,9 +274,10 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
179
274
|
assert.equal(promiseRejected, false);
|
|
180
275
|
|
|
181
276
|
// check the right listener was registered
|
|
182
|
-
assert.
|
|
183
|
-
assert.equal(mockMC.on.getCall(0).args[0],
|
|
184
|
-
assert.equal(mockMC.on.getCall(1).args[0],
|
|
277
|
+
assert.calledThrice(mockMC.on);
|
|
278
|
+
assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
|
|
279
|
+
assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
|
|
280
|
+
assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
|
|
185
281
|
const listener = mockMC.on.getCall(1).args[1];
|
|
186
282
|
|
|
187
283
|
// call the listener and pretend we are now connected
|
|
@@ -197,7 +293,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
197
293
|
assert.equal(promiseRejected, false);
|
|
198
294
|
|
|
199
295
|
// check that listener was removed
|
|
200
|
-
assert.
|
|
296
|
+
assert.calledThrice(mockMC.off);
|
|
201
297
|
|
|
202
298
|
assert.neverCalledWith(clearTimeoutSpy);
|
|
203
299
|
});
|
|
@@ -228,10 +324,11 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
228
324
|
assert.calledOnce(setTimeoutSpy);
|
|
229
325
|
|
|
230
326
|
// check the right listener was registered
|
|
231
|
-
assert.
|
|
232
|
-
assert.equal(mockMC.on.getCall(0).args[0],
|
|
233
|
-
assert.equal(mockMC.on.getCall(1).args[0],
|
|
234
|
-
|
|
327
|
+
assert.calledThrice(mockMC.on);
|
|
328
|
+
assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
|
|
329
|
+
assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
|
|
330
|
+
assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
|
|
331
|
+
const listener = mockMC.on.getCall(2).args[1];
|
|
235
332
|
|
|
236
333
|
// call the listener and pretend we are now connected
|
|
237
334
|
mockMC.getIceGatheringState.returns('complete');
|
|
@@ -249,7 +346,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
249
346
|
assert.equal(promiseRejected, false);
|
|
250
347
|
|
|
251
348
|
// check that listener was removed
|
|
252
|
-
assert.
|
|
349
|
+
assert.calledThrice(mockMC.off);
|
|
253
350
|
});
|
|
254
351
|
|
|
255
352
|
it(`reject with restart timer once if gathering state is not complete`, async () => {
|
|
@@ -276,9 +373,10 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
276
373
|
assert.equal(promiseRejected, false);
|
|
277
374
|
|
|
278
375
|
// check the right listener was registered
|
|
279
|
-
assert.
|
|
280
|
-
assert.equal(mockMC.on.getCall(0).args[0],
|
|
281
|
-
assert.equal(mockMC.on.getCall(1).args[0],
|
|
376
|
+
assert.calledThrice(mockMC.on);
|
|
377
|
+
assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
|
|
378
|
+
assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
|
|
379
|
+
assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
|
|
282
380
|
|
|
283
381
|
await clock.tickAsync(ICE_AND_DTLS_CONNECTION_TIMEOUT * 2);
|
|
284
382
|
await testUtils.flushPromises();
|
|
@@ -287,7 +385,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
287
385
|
assert.equal(promiseRejected, true);
|
|
288
386
|
|
|
289
387
|
// check that listener was removed
|
|
290
|
-
assert.
|
|
388
|
+
assert.calledThrice(mockMC.off);
|
|
291
389
|
|
|
292
390
|
assert.calledOnce(clearTimeoutSpy);
|
|
293
391
|
assert.calledTwice(setTimeoutSpy);
|
|
@@ -317,11 +415,12 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
317
415
|
assert.equal(promiseRejected, false);
|
|
318
416
|
|
|
319
417
|
// check the right listener was registered
|
|
320
|
-
assert.
|
|
321
|
-
assert.equal(mockMC.on.getCall(0).args[0],
|
|
322
|
-
assert.equal(mockMC.on.getCall(1).args[0],
|
|
418
|
+
assert.calledThrice(mockMC.on);
|
|
419
|
+
assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
|
|
420
|
+
assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
|
|
421
|
+
assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
|
|
323
422
|
const connectionStateListener = mockMC.on.getCall(0).args[1];
|
|
324
|
-
const iceGatheringListener = mockMC.on.getCall(
|
|
423
|
+
const iceGatheringListener = mockMC.on.getCall(2).args[1];
|
|
325
424
|
|
|
326
425
|
mockMC.getIceGatheringState.returns('complete');
|
|
327
426
|
iceGatheringListener();
|
|
@@ -335,7 +434,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
335
434
|
assert.equal(promiseRejected, false);
|
|
336
435
|
|
|
337
436
|
// check that listener was removed
|
|
338
|
-
assert.
|
|
437
|
+
assert.calledThrice(mockMC.off);
|
|
339
438
|
|
|
340
439
|
assert.calledTwice(clearTimeoutSpy);
|
|
341
440
|
assert.calledTwice(setTimeoutSpy);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as InternalMediaCoreModule from '@webex/internal-media-core';
|
|
2
2
|
import Media from '@webex/plugin-meetings/src/media/index';
|
|
3
3
|
import {assert} from '@webex/test-helper-chai';
|
|
4
4
|
import sinon from 'sinon';
|
|
5
5
|
import StaticConfig from '@webex/plugin-meetings/src/common/config';
|
|
6
|
-
import {forEach} from 'lodash';
|
|
7
6
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
8
7
|
|
|
9
8
|
describe('createMediaConnection', () => {
|
|
@@ -17,44 +16,44 @@ describe('createMediaConnection', () => {
|
|
|
17
16
|
id: 'roap media connection',
|
|
18
17
|
};
|
|
19
18
|
const fakeTrack = {
|
|
20
|
-
id: 'any fake track'
|
|
21
|
-
}
|
|
19
|
+
id: 'any fake track',
|
|
20
|
+
};
|
|
22
21
|
const fakeAudioStream = {
|
|
23
22
|
outputStream: {
|
|
24
23
|
getTracks: () => {
|
|
25
24
|
return [fakeTrack];
|
|
26
|
-
}
|
|
27
|
-
}
|
|
25
|
+
},
|
|
26
|
+
},
|
|
28
27
|
};
|
|
29
28
|
const fakeVideoStream = {
|
|
30
29
|
outputStream: {
|
|
31
30
|
getTracks: () => {
|
|
32
31
|
return [fakeTrack];
|
|
33
|
-
}
|
|
34
|
-
}
|
|
32
|
+
},
|
|
33
|
+
},
|
|
35
34
|
};
|
|
36
35
|
const fakeShareVideoStream = {
|
|
37
36
|
outputStream: {
|
|
38
37
|
getTracks: () => {
|
|
39
38
|
return [fakeTrack];
|
|
40
|
-
}
|
|
41
|
-
}
|
|
39
|
+
},
|
|
40
|
+
},
|
|
42
41
|
};
|
|
43
42
|
const fakeShareAudioStream = {
|
|
44
43
|
outputStream: {
|
|
45
44
|
getTracks: () => {
|
|
46
45
|
return [fakeTrack];
|
|
47
|
-
}
|
|
48
|
-
}
|
|
46
|
+
},
|
|
47
|
+
},
|
|
49
48
|
};
|
|
50
49
|
afterEach(() => {
|
|
51
50
|
sinon.restore();
|
|
52
|
-
clock.uninstall()
|
|
51
|
+
clock.uninstall();
|
|
53
52
|
});
|
|
54
53
|
|
|
55
54
|
it('creates a RoapMediaConnection when multistream is disabled', () => {
|
|
56
55
|
const roapMediaConnectionConstructorStub = sinon
|
|
57
|
-
.stub(
|
|
56
|
+
.stub(InternalMediaCoreModule, 'RoapMediaConnection')
|
|
58
57
|
.returns(fakeRoapMediaConnection);
|
|
59
58
|
|
|
60
59
|
StaticConfig.set({bandwidth: {audio: 123, video: 456, startBitrate: 999}});
|
|
@@ -81,7 +80,7 @@ describe('createMediaConnection', () => {
|
|
|
81
80
|
enableRtx: ENABLE_RTX,
|
|
82
81
|
enableExtmap: ENABLE_EXTMAP,
|
|
83
82
|
turnServerInfo: {
|
|
84
|
-
url: 'turn
|
|
83
|
+
url: 'turns:turn-server-url:443?transport=tcp',
|
|
85
84
|
username: 'turn username',
|
|
86
85
|
password: 'turn password',
|
|
87
86
|
},
|
|
@@ -92,7 +91,12 @@ describe('createMediaConnection', () => {
|
|
|
92
91
|
{
|
|
93
92
|
iceServers: [
|
|
94
93
|
{
|
|
95
|
-
urls: 'turn
|
|
94
|
+
urls: 'turn:turn-server-url:5004?transport=tcp',
|
|
95
|
+
username: 'turn username',
|
|
96
|
+
credential: 'turn password',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
urls: 'turns:turn-server-url:443?transport=tcp',
|
|
96
100
|
username: 'turn username',
|
|
97
101
|
credential: 'turn password',
|
|
98
102
|
},
|
|
@@ -132,7 +136,7 @@ describe('createMediaConnection', () => {
|
|
|
132
136
|
|
|
133
137
|
it('creates a MultistreamRoapMediaConnection when multistream is enabled', () => {
|
|
134
138
|
const multistreamRoapMediaConnectionConstructorStub = sinon
|
|
135
|
-
.stub(
|
|
139
|
+
.stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
|
|
136
140
|
.returns(fakeRoapMediaConnection);
|
|
137
141
|
|
|
138
142
|
Media.createMediaConnection(true, 'some debug id', webex, 'meeting id', 'correlationId', {
|
|
@@ -147,7 +151,7 @@ describe('createMediaConnection', () => {
|
|
|
147
151
|
},
|
|
148
152
|
},
|
|
149
153
|
turnServerInfo: {
|
|
150
|
-
url: 'turn
|
|
154
|
+
url: 'turns:turn-server-url:443?transport=tcp',
|
|
151
155
|
username: 'turn username',
|
|
152
156
|
password: 'turn password',
|
|
153
157
|
},
|
|
@@ -159,7 +163,12 @@ describe('createMediaConnection', () => {
|
|
|
159
163
|
{
|
|
160
164
|
iceServers: [
|
|
161
165
|
{
|
|
162
|
-
urls: 'turn
|
|
166
|
+
urls: 'turn:turn-server-url:5004?transport=tcp',
|
|
167
|
+
username: 'turn username',
|
|
168
|
+
credential: 'turn password',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
urls: 'turns:turn-server-url:443?transport=tcp',
|
|
163
172
|
username: 'turn username',
|
|
164
173
|
credential: 'turn password',
|
|
165
174
|
},
|
|
@@ -172,13 +181,16 @@ describe('createMediaConnection', () => {
|
|
|
172
181
|
|
|
173
182
|
[
|
|
174
183
|
{testCase: 'turnServerInfo is undefined', turnServerInfo: undefined},
|
|
175
|
-
{
|
|
184
|
+
{
|
|
185
|
+
testCase: 'turnServerInfo.url is empty string',
|
|
186
|
+
turnServerInfo: {url: '', username: 'turn username', password: 'turn password'},
|
|
187
|
+
},
|
|
176
188
|
].forEach(({testCase, turnServerInfo}) => {
|
|
177
189
|
it(`passes empty ICE servers array to MultistreamRoapMediaConnection if ${testCase} (multistream enabled)`, () => {
|
|
178
190
|
const multistreamRoapMediaConnectionConstructorStub = sinon
|
|
179
|
-
.stub(
|
|
191
|
+
.stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
|
|
180
192
|
.returns(fakeRoapMediaConnection);
|
|
181
|
-
|
|
193
|
+
|
|
182
194
|
Media.createMediaConnection(true, 'debug string', webex, 'meeting id', 'correlationId', {
|
|
183
195
|
mediaProperties: {
|
|
184
196
|
mediaDirection: {
|
|
@@ -199,13 +211,13 @@ describe('createMediaConnection', () => {
|
|
|
199
211
|
iceServers: [],
|
|
200
212
|
},
|
|
201
213
|
'meeting id'
|
|
202
|
-
|
|
214
|
+
);
|
|
203
215
|
});
|
|
204
216
|
});
|
|
205
|
-
|
|
217
|
+
|
|
206
218
|
it('does not pass bundlePolicy to MultistreamRoapMediaConnection if bundlePolicy is undefined', () => {
|
|
207
219
|
const multistreamRoapMediaConnectionConstructorStub = sinon
|
|
208
|
-
.stub(
|
|
220
|
+
.stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
|
|
209
221
|
.returns(fakeRoapMediaConnection);
|
|
210
222
|
|
|
211
223
|
Media.createMediaConnection(true, 'debug string', webex, 'meeting id', 'correlationId', {
|
|
@@ -233,11 +245,14 @@ describe('createMediaConnection', () => {
|
|
|
233
245
|
|
|
234
246
|
[
|
|
235
247
|
{testCase: 'turnServerInfo is undefined', turnServerInfo: undefined},
|
|
236
|
-
{
|
|
248
|
+
{
|
|
249
|
+
testCase: 'turnServerInfo.url is empty string',
|
|
250
|
+
turnServerInfo: {url: '', username: 'turn username', password: 'turn password'},
|
|
251
|
+
},
|
|
237
252
|
].forEach(({testCase, turnServerInfo}) => {
|
|
238
253
|
it(`passes empty ICE servers array to RoapMediaConnection if ${testCase} (multistream disabled)`, () => {
|
|
239
254
|
const roapMediaConnectionConstructorStub = sinon
|
|
240
|
-
.stub(
|
|
255
|
+
.stub(InternalMediaCoreModule, 'RoapMediaConnection')
|
|
241
256
|
.returns(fakeRoapMediaConnection);
|
|
242
257
|
|
|
243
258
|
StaticConfig.set({bandwidth: {audio: 123, video: 456, startBitrate: 999}});
|
|
@@ -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 {ConnectionState, MediaConnectionEventNames} 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], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
|
|
30
|
+
assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.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], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
|
|
55
|
+
assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.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], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
|
|
80
|
+
assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.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
|
+
});
|