@webex/plugin-meetings 3.3.1 → 3.4.0-next.10
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 +18 -9
- 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 +576 -374
- 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 +41 -35
- 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 +546 -115
- package/dist/reachability/index.js.map +1 -1
- package/dist/reconnection-manager/index.js +1 -1
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/rtcMetrics/index.js +26 -6
- package/dist/rtcMetrics/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 +28 -8
- 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 +6 -4
- 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 +107 -4
- package/dist/types/rtcMetrics/index.d.ts +11 -1
- 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 +18 -9
- package/src/meeting/connectionStateHandler.ts +65 -0
- package/src/meeting/index.ts +541 -298
- 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 +43 -43
- 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 +364 -30
- package/src/reconnection-manager/index.ts +1 -1
- package/src/rtcMetrics/index.ts +25 -5
- 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 +75 -34
- package/test/unit/spec/meeting/connectionStateHandler.ts +102 -0
- package/test/unit/spec/meeting/index.js +807 -185
- 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 +44 -3
- 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 +1398 -131
- package/test/unit/spec/rtcMetrics/index.ts +32 -0
- package/dist/mediaQualityMetrics/config.js +0 -321
- package/dist/mediaQualityMetrics/config.js.map +0 -1
- package/dist/networkQualityMonitor/index.js +0 -227
- package/dist/networkQualityMonitor/index.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/networkQualityMonitor/index.d.ts +0 -70
- 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/networkQualityMonitor/index.ts +0 -211
- 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/networkQualityMonitor/index.js +0 -99
- package/test/unit/spec/stats-analyzer/index.js +0 -1819
|
@@ -345,37 +345,39 @@ describe('plugin-meetings', () => {
|
|
|
345
345
|
});
|
|
346
346
|
|
|
347
347
|
describe('mutedByOthersChanged', () => {
|
|
348
|
-
it('throws an error if changedSelf is not provided', function() {
|
|
349
|
-
assert.throws(
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
assert.equal(SelfUtils.mutedByOthersChanged(null, { remoteMuted: false }), false);
|
|
348
|
+
it('throws an error if changedSelf is not provided', function () {
|
|
349
|
+
assert.throws(
|
|
350
|
+
() => SelfUtils.mutedByOthersChanged({}, null),
|
|
351
|
+
'New self must be defined to determine if self was muted by others.'
|
|
352
|
+
);
|
|
354
353
|
});
|
|
355
354
|
|
|
356
|
-
it('
|
|
357
|
-
assert.equal(SelfUtils.mutedByOthersChanged(null, {
|
|
355
|
+
it('return false when oldSelf is not defined', function () {
|
|
356
|
+
assert.equal(SelfUtils.mutedByOthersChanged(null, {remoteMuted: false}), false);
|
|
358
357
|
});
|
|
359
358
|
|
|
360
|
-
it('should return
|
|
361
|
-
assert.equal(SelfUtils.mutedByOthersChanged(
|
|
362
|
-
{ remoteMuted: false },
|
|
363
|
-
{ remoteMuted: true, selfIdentity: 'user1', modifiedBy: 'user1' }
|
|
364
|
-
), false);
|
|
359
|
+
it('should return true when remoteMuted is true on entry', function () {
|
|
360
|
+
assert.equal(SelfUtils.mutedByOthersChanged(null, {remoteMuted: true}), true);
|
|
365
361
|
});
|
|
366
362
|
|
|
367
|
-
it('should return true when remoteMuted values are different', function() {
|
|
368
|
-
assert.equal(
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
363
|
+
it('should return true when remoteMuted values are different', function () {
|
|
364
|
+
assert.equal(
|
|
365
|
+
SelfUtils.mutedByOthersChanged(
|
|
366
|
+
{remoteMuted: false},
|
|
367
|
+
{remoteMuted: true, selfIdentity: 'user1', modifiedBy: 'user2'}
|
|
368
|
+
),
|
|
369
|
+
true
|
|
370
|
+
);
|
|
372
371
|
});
|
|
373
372
|
|
|
374
|
-
it('should return true when remoteMuted is true and unmuteAllowed has changed', function() {
|
|
375
|
-
assert.equal(
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
373
|
+
it('should return true when remoteMuted is true and unmuteAllowed has changed', function () {
|
|
374
|
+
assert.equal(
|
|
375
|
+
SelfUtils.mutedByOthersChanged(
|
|
376
|
+
{remoteMuted: true, unmuteAllowed: false},
|
|
377
|
+
{remoteMuted: true, unmuteAllowed: true, selfIdentity: 'user1', modifiedBy: 'user2'}
|
|
378
|
+
),
|
|
379
|
+
true
|
|
380
|
+
);
|
|
379
381
|
});
|
|
380
382
|
});
|
|
381
383
|
|
|
@@ -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,60 +1,57 @@
|
|
|
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
|
-
import MockWebex from '@webex/test-helper-mock-webex';
|
|
8
6
|
|
|
9
7
|
describe('createMediaConnection', () => {
|
|
10
8
|
let clock;
|
|
11
9
|
beforeEach(() => {
|
|
12
10
|
clock = sinon.useFakeTimers();
|
|
13
11
|
});
|
|
14
|
-
const webex = MockWebex();
|
|
15
12
|
|
|
16
13
|
const fakeRoapMediaConnection = {
|
|
17
14
|
id: 'roap media connection',
|
|
18
15
|
};
|
|
19
16
|
const fakeTrack = {
|
|
20
|
-
id: 'any fake track'
|
|
21
|
-
}
|
|
17
|
+
id: 'any fake track',
|
|
18
|
+
};
|
|
22
19
|
const fakeAudioStream = {
|
|
23
20
|
outputStream: {
|
|
24
21
|
getTracks: () => {
|
|
25
22
|
return [fakeTrack];
|
|
26
|
-
}
|
|
27
|
-
}
|
|
23
|
+
},
|
|
24
|
+
},
|
|
28
25
|
};
|
|
29
26
|
const fakeVideoStream = {
|
|
30
27
|
outputStream: {
|
|
31
28
|
getTracks: () => {
|
|
32
29
|
return [fakeTrack];
|
|
33
|
-
}
|
|
34
|
-
}
|
|
30
|
+
},
|
|
31
|
+
},
|
|
35
32
|
};
|
|
36
33
|
const fakeShareVideoStream = {
|
|
37
34
|
outputStream: {
|
|
38
35
|
getTracks: () => {
|
|
39
36
|
return [fakeTrack];
|
|
40
|
-
}
|
|
41
|
-
}
|
|
37
|
+
},
|
|
38
|
+
},
|
|
42
39
|
};
|
|
43
40
|
const fakeShareAudioStream = {
|
|
44
41
|
outputStream: {
|
|
45
42
|
getTracks: () => {
|
|
46
43
|
return [fakeTrack];
|
|
47
|
-
}
|
|
48
|
-
}
|
|
44
|
+
},
|
|
45
|
+
},
|
|
49
46
|
};
|
|
50
47
|
afterEach(() => {
|
|
51
48
|
sinon.restore();
|
|
52
|
-
clock.uninstall()
|
|
49
|
+
clock.uninstall();
|
|
53
50
|
});
|
|
54
51
|
|
|
55
52
|
it('creates a RoapMediaConnection when multistream is disabled', () => {
|
|
56
53
|
const roapMediaConnectionConstructorStub = sinon
|
|
57
|
-
.stub(
|
|
54
|
+
.stub(InternalMediaCoreModule, 'RoapMediaConnection')
|
|
58
55
|
.returns(fakeRoapMediaConnection);
|
|
59
56
|
|
|
60
57
|
StaticConfig.set({bandwidth: {audio: 123, video: 456, startBitrate: 999}});
|
|
@@ -62,7 +59,7 @@ describe('createMediaConnection', () => {
|
|
|
62
59
|
const ENABLE_EXTMAP = false;
|
|
63
60
|
const ENABLE_RTX = true;
|
|
64
61
|
|
|
65
|
-
Media.createMediaConnection(false, 'some debug id',
|
|
62
|
+
Media.createMediaConnection(false, 'some debug id', 'meetingId', {
|
|
66
63
|
mediaProperties: {
|
|
67
64
|
mediaDirection: {
|
|
68
65
|
sendAudio: false,
|
|
@@ -81,7 +78,7 @@ describe('createMediaConnection', () => {
|
|
|
81
78
|
enableRtx: ENABLE_RTX,
|
|
82
79
|
enableExtmap: ENABLE_EXTMAP,
|
|
83
80
|
turnServerInfo: {
|
|
84
|
-
url: 'turn
|
|
81
|
+
url: 'turns:turn-server-url:443?transport=tcp',
|
|
85
82
|
username: 'turn username',
|
|
86
83
|
password: 'turn password',
|
|
87
84
|
},
|
|
@@ -92,7 +89,12 @@ describe('createMediaConnection', () => {
|
|
|
92
89
|
{
|
|
93
90
|
iceServers: [
|
|
94
91
|
{
|
|
95
|
-
urls: 'turn
|
|
92
|
+
urls: 'turn:turn-server-url:5004?transport=tcp',
|
|
93
|
+
username: 'turn username',
|
|
94
|
+
credential: 'turn password',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
urls: 'turns:turn-server-url:443?transport=tcp',
|
|
96
98
|
username: 'turn username',
|
|
97
99
|
credential: 'turn password',
|
|
98
100
|
},
|
|
@@ -132,10 +134,16 @@ describe('createMediaConnection', () => {
|
|
|
132
134
|
|
|
133
135
|
it('creates a MultistreamRoapMediaConnection when multistream is enabled', () => {
|
|
134
136
|
const multistreamRoapMediaConnectionConstructorStub = sinon
|
|
135
|
-
.stub(
|
|
137
|
+
.stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
|
|
136
138
|
.returns(fakeRoapMediaConnection);
|
|
137
139
|
|
|
138
|
-
|
|
140
|
+
const rtcMetrics = {
|
|
141
|
+
addMetrics: sinon.stub(),
|
|
142
|
+
closeMetrics: sinon.stub(),
|
|
143
|
+
sendMetricsInQueue: sinon.stub(),
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
Media.createMediaConnection(true, 'some debug id', 'meeting id', {
|
|
139
147
|
mediaProperties: {
|
|
140
148
|
mediaDirection: {
|
|
141
149
|
sendAudio: true,
|
|
@@ -146,8 +154,9 @@ describe('createMediaConnection', () => {
|
|
|
146
154
|
receiveShare: true,
|
|
147
155
|
},
|
|
148
156
|
},
|
|
157
|
+
rtcMetrics,
|
|
149
158
|
turnServerInfo: {
|
|
150
|
-
url: 'turn
|
|
159
|
+
url: 'turns:turn-server-url:443?transport=tcp',
|
|
151
160
|
username: 'turn username',
|
|
152
161
|
password: 'turn password',
|
|
153
162
|
},
|
|
@@ -159,7 +168,12 @@ describe('createMediaConnection', () => {
|
|
|
159
168
|
{
|
|
160
169
|
iceServers: [
|
|
161
170
|
{
|
|
162
|
-
urls: 'turn
|
|
171
|
+
urls: 'turn:turn-server-url:5004?transport=tcp',
|
|
172
|
+
username: 'turn username',
|
|
173
|
+
credential: 'turn password',
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
urls: 'turns:turn-server-url:443?transport=tcp',
|
|
163
177
|
username: 'turn username',
|
|
164
178
|
credential: 'turn password',
|
|
165
179
|
},
|
|
@@ -168,18 +182,42 @@ describe('createMediaConnection', () => {
|
|
|
168
182
|
},
|
|
169
183
|
'meeting id'
|
|
170
184
|
);
|
|
185
|
+
|
|
186
|
+
// check if rtcMetrics callbacks are configured correctly
|
|
187
|
+
const addMetricsCallback = multistreamRoapMediaConnectionConstructorStub.getCalls()[0].args[2];
|
|
188
|
+
const closeMetricsCallback = multistreamRoapMediaConnectionConstructorStub.getCalls()[0].args[3];
|
|
189
|
+
const sendMetricsInQueueCallback = multistreamRoapMediaConnectionConstructorStub.getCalls()[0].args[4];
|
|
190
|
+
|
|
191
|
+
assert.isFunction(addMetricsCallback);
|
|
192
|
+
assert.isFunction(closeMetricsCallback);
|
|
193
|
+
assert.isFunction(sendMetricsInQueueCallback);
|
|
194
|
+
|
|
195
|
+
const fakeMetricsData = {id: 'metrics data'};
|
|
196
|
+
|
|
197
|
+
addMetricsCallback(fakeMetricsData);
|
|
198
|
+
assert.calledOnceWithExactly(rtcMetrics.addMetrics, fakeMetricsData);
|
|
199
|
+
|
|
200
|
+
closeMetricsCallback();
|
|
201
|
+
assert.calledOnce(rtcMetrics.closeMetrics);
|
|
202
|
+
|
|
203
|
+
sendMetricsInQueueCallback();
|
|
204
|
+
assert.calledOnce(rtcMetrics.sendMetricsInQueue);
|
|
205
|
+
|
|
171
206
|
});
|
|
172
207
|
|
|
173
208
|
[
|
|
174
209
|
{testCase: 'turnServerInfo is undefined', turnServerInfo: undefined},
|
|
175
|
-
{
|
|
210
|
+
{
|
|
211
|
+
testCase: 'turnServerInfo.url is empty string',
|
|
212
|
+
turnServerInfo: {url: '', username: 'turn username', password: 'turn password'},
|
|
213
|
+
},
|
|
176
214
|
].forEach(({testCase, turnServerInfo}) => {
|
|
177
215
|
it(`passes empty ICE servers array to MultistreamRoapMediaConnection if ${testCase} (multistream enabled)`, () => {
|
|
178
216
|
const multistreamRoapMediaConnectionConstructorStub = sinon
|
|
179
|
-
.stub(
|
|
217
|
+
.stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
|
|
180
218
|
.returns(fakeRoapMediaConnection);
|
|
181
|
-
|
|
182
|
-
Media.createMediaConnection(true, 'debug string',
|
|
219
|
+
|
|
220
|
+
Media.createMediaConnection(true, 'debug string', 'meeting id', {
|
|
183
221
|
mediaProperties: {
|
|
184
222
|
mediaDirection: {
|
|
185
223
|
sendAudio: true,
|
|
@@ -199,16 +237,16 @@ describe('createMediaConnection', () => {
|
|
|
199
237
|
iceServers: [],
|
|
200
238
|
},
|
|
201
239
|
'meeting id'
|
|
202
|
-
|
|
240
|
+
);
|
|
203
241
|
});
|
|
204
242
|
});
|
|
205
|
-
|
|
243
|
+
|
|
206
244
|
it('does not pass bundlePolicy to MultistreamRoapMediaConnection if bundlePolicy is undefined', () => {
|
|
207
245
|
const multistreamRoapMediaConnectionConstructorStub = sinon
|
|
208
|
-
.stub(
|
|
246
|
+
.stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
|
|
209
247
|
.returns(fakeRoapMediaConnection);
|
|
210
248
|
|
|
211
|
-
Media.createMediaConnection(true, 'debug string',
|
|
249
|
+
Media.createMediaConnection(true, 'debug string', 'meeting id', {
|
|
212
250
|
mediaProperties: {
|
|
213
251
|
mediaDirection: {
|
|
214
252
|
sendAudio: true,
|
|
@@ -233,11 +271,14 @@ describe('createMediaConnection', () => {
|
|
|
233
271
|
|
|
234
272
|
[
|
|
235
273
|
{testCase: 'turnServerInfo is undefined', turnServerInfo: undefined},
|
|
236
|
-
{
|
|
274
|
+
{
|
|
275
|
+
testCase: 'turnServerInfo.url is empty string',
|
|
276
|
+
turnServerInfo: {url: '', username: 'turn username', password: 'turn password'},
|
|
277
|
+
},
|
|
237
278
|
].forEach(({testCase, turnServerInfo}) => {
|
|
238
279
|
it(`passes empty ICE servers array to RoapMediaConnection if ${testCase} (multistream disabled)`, () => {
|
|
239
280
|
const roapMediaConnectionConstructorStub = sinon
|
|
240
|
-
.stub(
|
|
281
|
+
.stub(InternalMediaCoreModule, 'RoapMediaConnection')
|
|
241
282
|
.returns(fakeRoapMediaConnection);
|
|
242
283
|
|
|
243
284
|
StaticConfig.set({bandwidth: {audio: 123, video: 456, startBitrate: 999}});
|
|
@@ -245,7 +286,7 @@ describe('createMediaConnection', () => {
|
|
|
245
286
|
const ENABLE_EXTMAP = false;
|
|
246
287
|
const ENABLE_RTX = true;
|
|
247
288
|
|
|
248
|
-
Media.createMediaConnection(false, 'some debug id',
|
|
289
|
+
Media.createMediaConnection(false, 'some debug id', 'meeting id', {
|
|
249
290
|
mediaProperties: {
|
|
250
291
|
mediaDirection: {
|
|
251
292
|
sendAudio: true,
|