@webex/plugin-meetings 3.0.0 → 3.1.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 +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +5 -4
- package/dist/constants.js +8 -4
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/interpretation/index.js +16 -2
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/mediaSharesUtils.js +15 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/selfUtils.js +5 -0
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.d.ts +61 -0
- package/dist/media/MediaConnectionAwaiter.js +163 -0
- package/dist/media/MediaConnectionAwaiter.js.map +1 -0
- package/dist/media/index.js +4 -1
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +4 -24
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/index.d.ts +26 -7
- package/dist/meeting/index.js +893 -677
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/muteState.d.ts +2 -8
- package/dist/meeting/muteState.js +37 -25
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.d.ts +3 -0
- package/dist/meeting/request.js +32 -23
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +1 -0
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +4 -1
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/index.d.ts +8 -0
- package/dist/meetings/index.js +20 -0
- package/dist/meetings/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.d.ts +2 -1
- package/dist/multistream/mediaRequestManager.js +1 -1
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.d.ts +2 -0
- package/dist/multistream/remoteMediaGroup.js +16 -2
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.d.ts +15 -0
- package/dist/multistream/remoteMediaManager.js +179 -65
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.d.ts +9 -1
- package/dist/multistream/sendSlotManager.js +22 -0
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/reachability/clusterReachability.d.ts +1 -0
- package/dist/reachability/clusterReachability.js +29 -15
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.d.ts +4 -0
- package/dist/reachability/index.js +18 -2
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +12 -10
- package/dist/reachability/request.js.map +1 -1
- package/dist/reachability/util.d.ts +7 -0
- package/dist/reachability/util.js +19 -0
- package/dist/reachability/util.js.map +1 -1
- package/dist/reconnection-manager/index.js +2 -1
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/index.d.ts +10 -2
- package/dist/roap/index.js +15 -0
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +3 -3
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.d.ts +64 -17
- package/dist/roap/turnDiscovery.js +307 -126
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/statsAnalyzer/index.js +53 -30
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/config.ts +1 -0
- package/src/constants.ts +7 -3
- package/src/index.ts +1 -0
- package/src/interpretation/index.ts +18 -1
- package/src/locus-info/mediaSharesUtils.ts +16 -0
- package/src/locus-info/selfUtils.ts +5 -0
- package/src/media/MediaConnectionAwaiter.ts +174 -0
- package/src/media/index.ts +3 -1
- package/src/media/properties.ts +6 -31
- package/src/meeting/index.ts +321 -106
- package/src/meeting/muteState.ts +34 -20
- package/src/meeting/request.ts +18 -2
- package/src/meeting/util.ts +1 -0
- package/src/meeting-info/utilv2.ts +2 -1
- package/src/meetings/index.ts +18 -0
- package/src/multistream/mediaRequestManager.ts +4 -1
- package/src/multistream/remoteMediaGroup.ts +19 -0
- package/src/multistream/remoteMediaManager.ts +101 -16
- package/src/multistream/sendSlotManager.ts +28 -0
- package/src/reachability/clusterReachability.ts +20 -5
- package/src/reachability/index.ts +24 -1
- package/src/reachability/request.ts +15 -11
- package/src/reachability/util.ts +21 -0
- package/src/reconnection-manager/index.ts +1 -1
- package/src/roap/index.ts +25 -3
- package/src/roap/request.ts +3 -3
- package/src/roap/turnDiscovery.ts +244 -78
- package/src/statsAnalyzer/index.ts +63 -27
- package/test/integration/spec/journey.js +14 -14
- package/test/integration/spec/space-meeting.js +1 -1
- package/test/unit/spec/interpretation/index.ts +39 -3
- package/test/unit/spec/locus-info/index.js +28 -19
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +9 -0
- package/test/unit/spec/locus-info/selfUtils.js +42 -12
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +344 -0
- package/test/unit/spec/media/index.ts +89 -78
- package/test/unit/spec/media/properties.ts +16 -70
- package/test/unit/spec/meeting/index.js +638 -139
- package/test/unit/spec/meeting/muteState.js +219 -67
- package/test/unit/spec/meeting/request.js +21 -0
- package/test/unit/spec/meeting/utils.js +6 -1
- package/test/unit/spec/meeting-info/utilv2.js +6 -0
- package/test/unit/spec/meetings/index.js +40 -20
- package/test/unit/spec/multistream/mediaRequestManager.ts +20 -2
- package/test/unit/spec/multistream/remoteMediaGroup.ts +79 -1
- package/test/unit/spec/multistream/remoteMediaManager.ts +199 -1
- package/test/unit/spec/multistream/sendSlotManager.ts +50 -18
- package/test/unit/spec/reachability/clusterReachability.ts +86 -22
- package/test/unit/spec/reachability/index.ts +197 -60
- package/test/unit/spec/reachability/request.js +15 -7
- package/test/unit/spec/reachability/util.ts +32 -2
- package/test/unit/spec/reconnection-manager/index.js +28 -0
- package/test/unit/spec/roap/index.ts +61 -6
- package/test/unit/spec/roap/turnDiscovery.ts +298 -16
- package/test/unit/spec/stats-analyzer/index.js +179 -0
- package/dist/member/member.types.d.ts +0 -11
- package/dist/member/member.types.js +0 -17
- package/dist/member/member.types.js.map +0 -1
- package/src/member/member.types.ts +0 -13
- /package/test/unit/spec/locus-info/{lib/selfConstant.js → selfConstant.js} +0 -0
|
@@ -15,21 +15,25 @@ describe('plugin-meetings', () => {
|
|
|
15
15
|
|
|
16
16
|
const fakeLocus = {info: 'this is a fake locus'};
|
|
17
17
|
|
|
18
|
-
const createFakeLocalStream = (id,
|
|
18
|
+
const createFakeLocalStream = (id, userMuted, systemMuted) => {
|
|
19
19
|
return {
|
|
20
20
|
id,
|
|
21
21
|
setServerMuted: sinon.stub(),
|
|
22
22
|
setUnmuteAllowed: sinon.stub(),
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
setUserMuted: sinon.stub(),
|
|
24
|
+
userMuted,
|
|
25
|
+
systemMuted,
|
|
26
|
+
get muted() {
|
|
27
|
+
return this.userMuted || this.systemMuted;
|
|
28
|
+
},
|
|
25
29
|
};
|
|
26
30
|
};
|
|
27
31
|
|
|
28
32
|
beforeEach(async () => {
|
|
29
33
|
meeting = {
|
|
30
34
|
mediaProperties: {
|
|
31
|
-
audioStream: createFakeLocalStream('fake audio stream', false),
|
|
32
|
-
videoStream: createFakeLocalStream('fake video stream', false),
|
|
35
|
+
audioStream: createFakeLocalStream('fake audio stream', false, false),
|
|
36
|
+
videoStream: createFakeLocalStream('fake video stream', false, false),
|
|
33
37
|
},
|
|
34
38
|
remoteMuted: false,
|
|
35
39
|
unmuteAllowed: true,
|
|
@@ -109,9 +113,9 @@ describe('plugin-meetings', () => {
|
|
|
109
113
|
assert.isTrue(audio.isRemotelyMuted());
|
|
110
114
|
});
|
|
111
115
|
|
|
112
|
-
it('does local unmute if localAudioUnmuteRequired is received', async () => {
|
|
113
|
-
// first we need to
|
|
114
|
-
meeting.mediaProperties.audioStream.
|
|
116
|
+
it('does local audio unmute if localAudioUnmuteRequired is received', async () => {
|
|
117
|
+
// first we need to have the local stream user muted
|
|
118
|
+
meeting.mediaProperties.audioStream.userMuted = true;
|
|
115
119
|
audio.handleLocalStreamChange(meeting);
|
|
116
120
|
|
|
117
121
|
assert.isTrue(audio.isMuted());
|
|
@@ -119,8 +123,12 @@ describe('plugin-meetings', () => {
|
|
|
119
123
|
MeetingUtil.remoteUpdateAudioVideo.resetHistory();
|
|
120
124
|
|
|
121
125
|
// now simulate server requiring us to locally unmute
|
|
126
|
+
// assuming setServerMuted succeeds at updating userMuted
|
|
127
|
+
meeting.mediaProperties.audioStream.setServerMuted = sinon.stub().callsFake((muted) => {
|
|
128
|
+
meeting.mediaProperties.audioStream.userMuted = muted;
|
|
129
|
+
});
|
|
122
130
|
audio.handleServerLocalUnmuteRequired(meeting);
|
|
123
|
-
|
|
131
|
+
|
|
124
132
|
await testUtils.flushPromises();
|
|
125
133
|
|
|
126
134
|
// check that local stream was unmuted
|
|
@@ -137,9 +145,41 @@ describe('plugin-meetings', () => {
|
|
|
137
145
|
assert.isFalse(audio.isMuted());
|
|
138
146
|
});
|
|
139
147
|
|
|
148
|
+
it('handles localAudioUnmuteRequired but does not send unmute to server if system is muted', async () => {
|
|
149
|
+
// first we need to have the local stream user muted and system muted
|
|
150
|
+
meeting.mediaProperties.audioStream.userMuted = true;
|
|
151
|
+
meeting.mediaProperties.audioStream.systemMuted = true;
|
|
152
|
+
audio.handleLocalStreamChange(meeting);
|
|
153
|
+
|
|
154
|
+
assert.isTrue(audio.isMuted());
|
|
155
|
+
|
|
156
|
+
MeetingUtil.remoteUpdateAudioVideo.resetHistory();
|
|
157
|
+
|
|
158
|
+
// now simulate server requiring us to locally unmute
|
|
159
|
+
// assuming setServerMuted succeeds at updating userMuted
|
|
160
|
+
meeting.mediaProperties.audioStream.setServerMuted = sinon.stub().callsFake((muted) => {
|
|
161
|
+
meeting.mediaProperties.audioStream.userMuted = muted;
|
|
162
|
+
});
|
|
163
|
+
audio.handleServerLocalUnmuteRequired(meeting);
|
|
164
|
+
|
|
165
|
+
await testUtils.flushPromises();
|
|
166
|
+
|
|
167
|
+
// check that local stream was unmuted
|
|
168
|
+
assert.calledWith(
|
|
169
|
+
meeting.mediaProperties.audioStream.setServerMuted,
|
|
170
|
+
false,
|
|
171
|
+
'localUnmuteRequired'
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
// system was muted so local unmute was not sent to server
|
|
175
|
+
assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
|
|
176
|
+
|
|
177
|
+
assert.isTrue(audio.isMuted());
|
|
178
|
+
});
|
|
179
|
+
|
|
140
180
|
it('does local video unmute if localVideoUnmuteRequired is received', async () => {
|
|
141
|
-
// first we need to
|
|
142
|
-
meeting.mediaProperties.videoStream.
|
|
181
|
+
// first we need to have the local stream user muted
|
|
182
|
+
meeting.mediaProperties.videoStream.userMuted = true;
|
|
143
183
|
video.handleLocalStreamChange(meeting);
|
|
144
184
|
|
|
145
185
|
assert.isTrue(video.isMuted());
|
|
@@ -147,7 +187,12 @@ describe('plugin-meetings', () => {
|
|
|
147
187
|
MeetingUtil.remoteUpdateAudioVideo.resetHistory();
|
|
148
188
|
|
|
149
189
|
// now simulate server requiring us to locally unmute
|
|
190
|
+
// assuming setServerMuted succeeds at updating userMuted
|
|
191
|
+
meeting.mediaProperties.videoStream.setServerMuted = sinon.stub().callsFake((muted) => {
|
|
192
|
+
meeting.mediaProperties.videoStream.userMuted = muted;
|
|
193
|
+
});
|
|
150
194
|
video.handleServerLocalUnmuteRequired(meeting);
|
|
195
|
+
|
|
151
196
|
await testUtils.flushPromises();
|
|
152
197
|
|
|
153
198
|
// check that local stream was unmuted
|
|
@@ -164,11 +209,43 @@ describe('plugin-meetings', () => {
|
|
|
164
209
|
assert.isFalse(video.isMuted());
|
|
165
210
|
});
|
|
166
211
|
|
|
212
|
+
it('handles localVideoUnmuteRequired but does not send unmute to server if system is muted', async () => {
|
|
213
|
+
// first we need to have the local stream user muted and system muted
|
|
214
|
+
meeting.mediaProperties.videoStream.userMuted = true;
|
|
215
|
+
meeting.mediaProperties.videoStream.systemMuted = true;
|
|
216
|
+
audio.handleLocalStreamChange(meeting);
|
|
217
|
+
|
|
218
|
+
assert.isTrue(video.isMuted());
|
|
219
|
+
|
|
220
|
+
MeetingUtil.remoteUpdateAudioVideo.resetHistory();
|
|
221
|
+
|
|
222
|
+
// now simulate server requiring us to locally unmute
|
|
223
|
+
// assuming setServerMuted succeeds at updating userMuted
|
|
224
|
+
meeting.mediaProperties.videoStream.setServerMuted = sinon.stub().callsFake((muted) => {
|
|
225
|
+
meeting.mediaProperties.videoStream.userMuted = muted;
|
|
226
|
+
});
|
|
227
|
+
video.handleServerLocalUnmuteRequired(meeting);
|
|
228
|
+
|
|
229
|
+
await testUtils.flushPromises();
|
|
230
|
+
|
|
231
|
+
// check that local stream was unmuted
|
|
232
|
+
assert.calledWith(
|
|
233
|
+
meeting.mediaProperties.videoStream.setServerMuted,
|
|
234
|
+
false,
|
|
235
|
+
'localUnmuteRequired'
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
// system was muted so local unmute was not sent to server
|
|
239
|
+
assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
|
|
240
|
+
|
|
241
|
+
assert.isTrue(video.isMuted());
|
|
242
|
+
});
|
|
243
|
+
|
|
167
244
|
describe('#isLocallyMuted()', () => {
|
|
168
245
|
it('does not consider remote mute status for audio', async () => {
|
|
169
246
|
// simulate being already remote muted and locally unmuted
|
|
170
247
|
meeting.remoteMuted = true;
|
|
171
|
-
meeting.mediaProperties.audioStream.
|
|
248
|
+
meeting.mediaProperties.audioStream.userMuted = false;
|
|
172
249
|
|
|
173
250
|
// create a new MuteState instance
|
|
174
251
|
audio = createMuteState(AUDIO, meeting, true);
|
|
@@ -182,7 +259,7 @@ describe('plugin-meetings', () => {
|
|
|
182
259
|
it('does not consider remote mute status for video', async () => {
|
|
183
260
|
// simulate being already remote muted
|
|
184
261
|
meeting.remoteVideoMuted = true;
|
|
185
|
-
meeting.mediaProperties.videoStream.
|
|
262
|
+
meeting.mediaProperties.videoStream.userMuted = false;
|
|
186
263
|
|
|
187
264
|
// create a new MuteState instance
|
|
188
265
|
video = createMuteState(VIDEO, meeting, true);
|
|
@@ -202,27 +279,44 @@ describe('plugin-meetings', () => {
|
|
|
202
279
|
await testUtils.flushPromises();
|
|
203
280
|
});
|
|
204
281
|
|
|
205
|
-
const
|
|
206
|
-
meeting.mediaProperties.audioStream.
|
|
207
|
-
audio.handleLocalStreamMuteStateChange(meeting
|
|
282
|
+
const simulateAudioUserMuteChange = async (muteValue) => {
|
|
283
|
+
meeting.mediaProperties.audioStream.userMuted = muteValue;
|
|
284
|
+
audio.handleLocalStreamMuteStateChange(meeting);
|
|
285
|
+
|
|
286
|
+
await testUtils.flushPromises();
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const simulateAudioSystemMuteChange = async (muteValue) => {
|
|
290
|
+
meeting.mediaProperties.audioStream.systemMuted = muteValue;
|
|
291
|
+
audio.handleLocalStreamMuteStateChange(meeting);
|
|
208
292
|
|
|
209
293
|
await testUtils.flushPromises();
|
|
210
294
|
};
|
|
211
295
|
|
|
212
|
-
const
|
|
213
|
-
meeting.mediaProperties.videoStream.
|
|
214
|
-
video.handleLocalStreamMuteStateChange(meeting
|
|
296
|
+
const simulateVideoUserMuteChange = async (muteValue) => {
|
|
297
|
+
meeting.mediaProperties.videoStream.userMuted = muteValue;
|
|
298
|
+
video.handleLocalStreamMuteStateChange(meeting);
|
|
215
299
|
|
|
216
300
|
await testUtils.flushPromises();
|
|
217
301
|
};
|
|
218
302
|
|
|
219
|
-
it('returns correct value in isMuted() methods after local stream is muted/unmuted', async () => {
|
|
303
|
+
it('returns correct value in isMuted() methods after local stream is user muted/unmuted', async () => {
|
|
220
304
|
// mute
|
|
221
|
-
await
|
|
305
|
+
await simulateAudioUserMuteChange(true);
|
|
222
306
|
assert.isTrue(audio.isMuted());
|
|
223
307
|
|
|
224
308
|
// unmute
|
|
225
|
-
await
|
|
309
|
+
await simulateAudioUserMuteChange(false);
|
|
310
|
+
assert.isFalse(audio.isMuted());
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it('returns correct value in isMuted() methods after local stream is system muted/unmuted', async () => {
|
|
314
|
+
// mute
|
|
315
|
+
await simulateAudioSystemMuteChange(true);
|
|
316
|
+
assert.isTrue(audio.isMuted());
|
|
317
|
+
|
|
318
|
+
// unmute
|
|
319
|
+
await simulateAudioSystemMuteChange(false);
|
|
226
320
|
assert.isFalse(audio.isMuted());
|
|
227
321
|
});
|
|
228
322
|
|
|
@@ -231,7 +325,7 @@ describe('plugin-meetings', () => {
|
|
|
231
325
|
audio.handleServerRemoteMuteUpdate(meeting, true, true);
|
|
232
326
|
|
|
233
327
|
// unmute
|
|
234
|
-
await
|
|
328
|
+
await simulateAudioUserMuteChange(false);
|
|
235
329
|
|
|
236
330
|
// check that remote unmute was sent to server
|
|
237
331
|
assert.calledOnce(meeting.members.muteMember);
|
|
@@ -245,7 +339,7 @@ describe('plugin-meetings', () => {
|
|
|
245
339
|
video.handleServerRemoteMuteUpdate(meeting, true, true);
|
|
246
340
|
|
|
247
341
|
// unmute
|
|
248
|
-
await
|
|
342
|
+
await simulateVideoUserMuteChange(false);
|
|
249
343
|
|
|
250
344
|
// check that remote unmute was sent to server
|
|
251
345
|
assert.calledOnce(meeting.members.muteMember);
|
|
@@ -259,7 +353,7 @@ describe('plugin-meetings', () => {
|
|
|
259
353
|
video.handleServerRemoteMuteUpdate(meeting, false, true);
|
|
260
354
|
|
|
261
355
|
// unmute
|
|
262
|
-
await
|
|
356
|
+
await simulateVideoUserMuteChange(false);
|
|
263
357
|
|
|
264
358
|
// check that remote unmute was not sent to server
|
|
265
359
|
assert.notCalled(meeting.members.muteMember);
|
|
@@ -270,7 +364,7 @@ describe('plugin-meetings', () => {
|
|
|
270
364
|
it('calls setServerMuted with "clientRequestFailed" when server request for local mute fails', async () => {
|
|
271
365
|
MeetingUtil.remoteUpdateAudioVideo = sinon.stub().rejects(new Error('fake error'));
|
|
272
366
|
|
|
273
|
-
await
|
|
367
|
+
await simulateAudioUserMuteChange(true);
|
|
274
368
|
|
|
275
369
|
assert.calledOnceWithExactly(
|
|
276
370
|
meeting.mediaProperties.audioStream.setServerMuted,
|
|
@@ -289,7 +383,7 @@ describe('plugin-meetings', () => {
|
|
|
289
383
|
meeting.members.muteMember = sinon.stub().rejects();
|
|
290
384
|
meeting.mediaProperties.audioStream.setServerMuted.resetHistory();
|
|
291
385
|
|
|
292
|
-
await
|
|
386
|
+
await simulateAudioUserMuteChange(false);
|
|
293
387
|
|
|
294
388
|
assert.calledOnceWithExactly(
|
|
295
389
|
meeting.mediaProperties.audioStream.setServerMuted,
|
|
@@ -313,11 +407,11 @@ describe('plugin-meetings', () => {
|
|
|
313
407
|
|
|
314
408
|
// the stream is initially unmuted
|
|
315
409
|
// simulate many mute changes with the last one matching the first one
|
|
316
|
-
await
|
|
317
|
-
await
|
|
318
|
-
await
|
|
319
|
-
await
|
|
320
|
-
await
|
|
410
|
+
await simulateAudioUserMuteChange(true);
|
|
411
|
+
await simulateAudioUserMuteChange(false);
|
|
412
|
+
await simulateAudioUserMuteChange(true);
|
|
413
|
+
await simulateAudioUserMuteChange(false);
|
|
414
|
+
await simulateAudioUserMuteChange(true);
|
|
321
415
|
|
|
322
416
|
// so far there should have been only 1 request to server (because our stub hasn't resolved yet
|
|
323
417
|
// and MuteState sends only 1 server request at a time)
|
|
@@ -342,8 +436,8 @@ describe('plugin-meetings', () => {
|
|
|
342
436
|
);
|
|
343
437
|
|
|
344
438
|
// 2 client requests, one after another without waiting for first one to resolve
|
|
345
|
-
await
|
|
346
|
-
await
|
|
439
|
+
await simulateAudioUserMuteChange(true);
|
|
440
|
+
await simulateAudioUserMuteChange(false);
|
|
347
441
|
|
|
348
442
|
assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
|
|
349
443
|
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, true, undefined);
|
|
@@ -364,7 +458,7 @@ describe('plugin-meetings', () => {
|
|
|
364
458
|
|
|
365
459
|
it('does not send remote mute for video', async () => {
|
|
366
460
|
// mute
|
|
367
|
-
await
|
|
461
|
+
await simulateVideoUserMuteChange(true);
|
|
368
462
|
|
|
369
463
|
assert.isTrue(video.isMuted());
|
|
370
464
|
|
|
@@ -376,7 +470,7 @@ describe('plugin-meetings', () => {
|
|
|
376
470
|
meeting.members.muteMember.resetHistory();
|
|
377
471
|
|
|
378
472
|
// unmute
|
|
379
|
-
await
|
|
473
|
+
await simulateVideoUserMuteChange(false);
|
|
380
474
|
|
|
381
475
|
assert.isFalse(video.isMuted());
|
|
382
476
|
|
|
@@ -390,22 +484,22 @@ describe('plugin-meetings', () => {
|
|
|
390
484
|
meeting.video = video;
|
|
391
485
|
|
|
392
486
|
// mute audio -> the call to remoteUpdateAudioVideo should have video undefined
|
|
393
|
-
await
|
|
487
|
+
await simulateAudioUserMuteChange(true);
|
|
394
488
|
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, true, undefined);
|
|
395
489
|
MeetingUtil.remoteUpdateAudioVideo.resetHistory();
|
|
396
490
|
|
|
397
491
|
// now mute video -> the call to remoteUpdateAudioVideo should have unmute for video and undefined for audio
|
|
398
|
-
await
|
|
492
|
+
await simulateVideoUserMuteChange(true);
|
|
399
493
|
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, true);
|
|
400
494
|
MeetingUtil.remoteUpdateAudioVideo.resetHistory();
|
|
401
495
|
|
|
402
496
|
// now unmute the audio -> the call to remoteUpdateAudioVideo should have video undefined
|
|
403
|
-
await
|
|
497
|
+
await simulateAudioUserMuteChange(false);
|
|
404
498
|
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, false, undefined);
|
|
405
499
|
MeetingUtil.remoteUpdateAudioVideo.resetHistory();
|
|
406
500
|
|
|
407
501
|
// unmute video -> the call to remoteUpdateAudioVideo should have audio undefined
|
|
408
|
-
await
|
|
502
|
+
await simulateVideoUserMuteChange(false);
|
|
409
503
|
assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, false);
|
|
410
504
|
});
|
|
411
505
|
});
|
|
@@ -414,12 +508,13 @@ describe('plugin-meetings', () => {
|
|
|
414
508
|
let meeting;
|
|
415
509
|
let muteState;
|
|
416
510
|
let setServerMutedSpy;
|
|
417
|
-
let
|
|
511
|
+
let setUserMutedSpy, setUnmuteAllowedSpy;
|
|
418
512
|
|
|
419
513
|
const setupMeeting = (
|
|
420
514
|
mediaType,
|
|
421
515
|
remoteMuted = false,
|
|
422
|
-
|
|
516
|
+
userMuted = false,
|
|
517
|
+
systemMuted = false,
|
|
423
518
|
defineStreams = true
|
|
424
519
|
) => {
|
|
425
520
|
const remoteMuteField = mediaType === AUDIO ? 'remoteMuted' : 'remoteVideoMuted';
|
|
@@ -427,10 +522,10 @@ describe('plugin-meetings', () => {
|
|
|
427
522
|
meeting = {
|
|
428
523
|
mediaProperties: {
|
|
429
524
|
audioStream: defineStreams
|
|
430
|
-
? createFakeLocalStream('fake audio stream',
|
|
525
|
+
? createFakeLocalStream('fake audio stream', userMuted, systemMuted)
|
|
431
526
|
: undefined,
|
|
432
527
|
videoStream: defineStreams
|
|
433
|
-
? createFakeLocalStream('fake video stream',
|
|
528
|
+
? createFakeLocalStream('fake video stream', userMuted, systemMuted)
|
|
434
529
|
: undefined,
|
|
435
530
|
},
|
|
436
531
|
[remoteMuteField]: remoteMuted,
|
|
@@ -447,8 +542,14 @@ describe('plugin-meetings', () => {
|
|
|
447
542
|
};
|
|
448
543
|
};
|
|
449
544
|
|
|
450
|
-
const setup = async (
|
|
451
|
-
|
|
545
|
+
const setup = async (
|
|
546
|
+
mediaType,
|
|
547
|
+
remoteMuted = false,
|
|
548
|
+
userMuted = false,
|
|
549
|
+
systemMuted = false,
|
|
550
|
+
defineStreams = true
|
|
551
|
+
) => {
|
|
552
|
+
setupMeeting(mediaType, remoteMuted, userMuted, systemMuted, defineStreams);
|
|
452
553
|
|
|
453
554
|
muteState = createMuteState(mediaType, meeting, true);
|
|
454
555
|
muteState.handleLocalStreamChange(meeting);
|
|
@@ -467,10 +568,10 @@ describe('plugin-meetings', () => {
|
|
|
467
568
|
mediaType === AUDIO
|
|
468
569
|
? meeting.mediaProperties.audioStream?.setServerMuted
|
|
469
570
|
: meeting.mediaProperties.videoStream?.setServerMuted;
|
|
470
|
-
|
|
571
|
+
setUserMutedSpy =
|
|
471
572
|
mediaType === AUDIO
|
|
472
|
-
? meeting.mediaProperties.audioStream?.
|
|
473
|
-
: meeting.mediaProperties.videoStream?.
|
|
573
|
+
? meeting.mediaProperties.audioStream?.setUserMuted
|
|
574
|
+
: meeting.mediaProperties.videoStream?.setUserMuted;
|
|
474
575
|
|
|
475
576
|
clearSpies();
|
|
476
577
|
};
|
|
@@ -478,8 +579,25 @@ describe('plugin-meetings', () => {
|
|
|
478
579
|
const clearSpies = () => {
|
|
479
580
|
setUnmuteAllowedSpy?.resetHistory();
|
|
480
581
|
setServerMutedSpy?.resetHistory();
|
|
481
|
-
|
|
582
|
+
setUserMutedSpy?.resetHistory();
|
|
482
583
|
};
|
|
584
|
+
|
|
585
|
+
const simulateUserMute = (mediaType, mute) => {
|
|
586
|
+
if (mediaType === AUDIO) {
|
|
587
|
+
meeting.mediaProperties.audioStream.userMuted = mute;
|
|
588
|
+
} else {
|
|
589
|
+
meeting.mediaProperties.videoStream.userMuted = mute;
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
const simulateSystemMute = (mediaType, mute) => {
|
|
594
|
+
if (mediaType === AUDIO) {
|
|
595
|
+
meeting.mediaProperties.audioStream.systemMuted = mute;
|
|
596
|
+
} else {
|
|
597
|
+
meeting.mediaProperties.videoStream.systemMuted = mute;
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
|
|
483
601
|
const tests = [
|
|
484
602
|
{mediaType: AUDIO, title: 'audio'},
|
|
485
603
|
{mediaType: VIDEO, title: 'video'},
|
|
@@ -513,16 +631,17 @@ describe('plugin-meetings', () => {
|
|
|
513
631
|
const setupWithoutInit = async (
|
|
514
632
|
mediaType,
|
|
515
633
|
remoteMuted = false,
|
|
516
|
-
|
|
634
|
+
userMuted = false,
|
|
635
|
+
systemMuted = false,
|
|
517
636
|
defineStreams = true
|
|
518
637
|
) => {
|
|
519
|
-
setupMeeting(mediaType, remoteMuted,
|
|
638
|
+
setupMeeting(mediaType, remoteMuted, userMuted, systemMuted, defineStreams);
|
|
520
639
|
|
|
521
640
|
muteState = new MuteState(mediaType, meeting, true);
|
|
522
641
|
};
|
|
523
642
|
|
|
524
643
|
it('nothing goes bad when stream is undefined', async () => {
|
|
525
|
-
await setupWithoutInit(mediaType, false, false, false);
|
|
644
|
+
await setupWithoutInit(mediaType, false, false, false, false);
|
|
526
645
|
setupSpies(mediaType);
|
|
527
646
|
|
|
528
647
|
muteState.init(meeting);
|
|
@@ -530,8 +649,20 @@ describe('plugin-meetings', () => {
|
|
|
530
649
|
assert.isTrue(muteState.state.client.localMute);
|
|
531
650
|
});
|
|
532
651
|
|
|
533
|
-
it('tests when stream muted is true and remoteMuted is false', async () => {
|
|
534
|
-
await setupWithoutInit(mediaType, false, true);
|
|
652
|
+
it('tests when stream user muted is true and remoteMuted is false', async () => {
|
|
653
|
+
await setupWithoutInit(mediaType, false, true, false, true);
|
|
654
|
+
setupSpies(mediaType);
|
|
655
|
+
|
|
656
|
+
muteState.init(meeting);
|
|
657
|
+
|
|
658
|
+
assert.calledWith(setUnmuteAllowedSpy, muteState.state.server.unmuteAllowed);
|
|
659
|
+
assert.notCalled(setServerMutedSpy);
|
|
660
|
+
assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
|
|
661
|
+
assert.isTrue(muteState.state.client.localMute);
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
it('tests when stream system muted is true and remoteMuted is false', async () => {
|
|
665
|
+
await setupWithoutInit(mediaType, false, false, true, true);
|
|
535
666
|
setupSpies(mediaType);
|
|
536
667
|
|
|
537
668
|
muteState.init(meeting);
|
|
@@ -542,8 +673,8 @@ describe('plugin-meetings', () => {
|
|
|
542
673
|
assert.isTrue(muteState.state.client.localMute);
|
|
543
674
|
});
|
|
544
675
|
|
|
545
|
-
it('tests when stream muted
|
|
546
|
-
await setupWithoutInit(mediaType, false, false);
|
|
676
|
+
it('tests when both stream user muted and system muted are false and remoteMuted is false', async () => {
|
|
677
|
+
await setupWithoutInit(mediaType, false, false, false, true);
|
|
547
678
|
setupSpies(mediaType);
|
|
548
679
|
|
|
549
680
|
muteState.init(meeting);
|
|
@@ -556,7 +687,7 @@ describe('plugin-meetings', () => {
|
|
|
556
687
|
|
|
557
688
|
it('tests when remoteMuted is true', async () => {
|
|
558
689
|
// testing that muteLocalStream is called
|
|
559
|
-
await setupWithoutInit(mediaType, true);
|
|
690
|
+
await setupWithoutInit(mediaType, true, false, false, true);
|
|
560
691
|
setupSpies(mediaType);
|
|
561
692
|
|
|
562
693
|
muteState.init(meeting);
|
|
@@ -568,27 +699,48 @@ describe('plugin-meetings', () => {
|
|
|
568
699
|
|
|
569
700
|
describe('#handleLocalStreamMuteStateChange', () => {
|
|
570
701
|
it('checks when ignoreMuteStateChange is true nothing changes', async () => {
|
|
571
|
-
await setup(mediaType, false, false);
|
|
702
|
+
await setup(mediaType, false, false, false, true);
|
|
572
703
|
muteState.ignoreMuteStateChange = true;
|
|
573
704
|
|
|
574
|
-
|
|
705
|
+
simulateUserMute(mediaType, true);
|
|
706
|
+
muteState.handleLocalStreamMuteStateChange(meeting);
|
|
575
707
|
assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
|
|
576
708
|
|
|
577
709
|
assert.isFalse(muteState.state.client.localMute);
|
|
578
710
|
});
|
|
579
711
|
|
|
580
|
-
it('tests localMute - true to false', async () => {
|
|
581
|
-
await setup(mediaType, false, true);
|
|
712
|
+
it('tests localMute - user mute from true to false', async () => {
|
|
713
|
+
await setup(mediaType, false, true, false, true);
|
|
714
|
+
|
|
715
|
+
simulateUserMute(mediaType, false);
|
|
716
|
+
muteState.handleLocalStreamMuteStateChange(meeting);
|
|
717
|
+
assert.equal(muteState.state.client.localMute, false);
|
|
718
|
+
assert.called(MeetingUtil.remoteUpdateAudioVideo);
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
it('tests localMute - user mute from false to true', async () => {
|
|
722
|
+
await setup(mediaType, false, false, false, true);
|
|
723
|
+
|
|
724
|
+
simulateUserMute(mediaType, true);
|
|
725
|
+
muteState.handleLocalStreamMuteStateChange(meeting);
|
|
726
|
+
assert.equal(muteState.state.client.localMute, true);
|
|
727
|
+
assert.called(MeetingUtil.remoteUpdateAudioVideo);
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
it('tests localMute - system mute from true to false', async () => {
|
|
731
|
+
await setup(mediaType, false, false, true, true);
|
|
582
732
|
|
|
583
|
-
|
|
733
|
+
simulateSystemMute(mediaType, false);
|
|
734
|
+
muteState.handleLocalStreamMuteStateChange(meeting);
|
|
584
735
|
assert.equal(muteState.state.client.localMute, false);
|
|
585
736
|
assert.called(MeetingUtil.remoteUpdateAudioVideo);
|
|
586
737
|
});
|
|
587
738
|
|
|
588
|
-
it('tests localMute - false to true', async () => {
|
|
589
|
-
await setup(mediaType, false, false);
|
|
739
|
+
it('tests localMute - system mute from false to true', async () => {
|
|
740
|
+
await setup(mediaType, false, false, false, true);
|
|
590
741
|
|
|
591
|
-
|
|
742
|
+
simulateSystemMute(mediaType, true);
|
|
743
|
+
muteState.handleLocalStreamMuteStateChange(meeting);
|
|
592
744
|
assert.equal(muteState.state.client.localMute, true);
|
|
593
745
|
assert.called(MeetingUtil.remoteUpdateAudioVideo);
|
|
594
746
|
});
|
|
@@ -609,7 +761,7 @@ describe('plugin-meetings', () => {
|
|
|
609
761
|
muteState.state.client.localMute,
|
|
610
762
|
'somereason'
|
|
611
763
|
);
|
|
612
|
-
assert.notCalled(
|
|
764
|
+
assert.notCalled(setUserMutedSpy);
|
|
613
765
|
});
|
|
614
766
|
|
|
615
767
|
it('nothing explodes when streams are undefined', async () => {
|
|
@@ -194,12 +194,14 @@ describe('plugin-meetings', () => {
|
|
|
194
194
|
const roapMessage = 'roap-message';
|
|
195
195
|
const permissionToken = 'permission-token';
|
|
196
196
|
const installationId = 'installationId';
|
|
197
|
+
const reachability = 'reachability';
|
|
197
198
|
|
|
198
199
|
await meetingsRequest.joinMeeting({
|
|
199
200
|
locusUrl,
|
|
200
201
|
deviceUrl,
|
|
201
202
|
correlationId,
|
|
202
203
|
roapMessage,
|
|
204
|
+
reachability,
|
|
203
205
|
permissionToken,
|
|
204
206
|
});
|
|
205
207
|
const requestParams = meetingsRequest.request.getCall(0).args[0];
|
|
@@ -212,6 +214,9 @@ describe('plugin-meetings', () => {
|
|
|
212
214
|
assert.equal(requestParams.body.permissionToken, 'permission-token');
|
|
213
215
|
assert.equal(requestParams.body.device.regionCode, 'WEST-COAST');
|
|
214
216
|
assert.include(requestParams.body.device.localIp, '127.0.0');
|
|
217
|
+
assert.deepEqual(requestParams.body.localMedias, [
|
|
218
|
+
{localSdp: '{"roapMessage":"roap-message","reachability":"reachability"}'},
|
|
219
|
+
]);
|
|
215
220
|
|
|
216
221
|
assert.calledOnceWithExactly(anonymizeIpSpy, '127.0.0.1');
|
|
217
222
|
});
|
|
@@ -365,6 +370,22 @@ describe('plugin-meetings', () => {
|
|
|
365
370
|
assert.deepEqual(requestParams.body.locale, undefined);
|
|
366
371
|
});
|
|
367
372
|
|
|
373
|
+
it('adds alias to request when they are provided', async () => {
|
|
374
|
+
await meetingsRequest.joinMeeting({
|
|
375
|
+
alias: 'assigned name',
|
|
376
|
+
});
|
|
377
|
+
const requestParams = meetingsRequest.request.getCall(0).args[0];
|
|
378
|
+
|
|
379
|
+
assert.deepEqual(requestParams.body.alias, 'assigned name');
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
it('does not add alias to request when they are not provided', async () => {
|
|
383
|
+
await meetingsRequest.joinMeeting({});
|
|
384
|
+
const requestParams = meetingsRequest.request.getCall(0).args[0];
|
|
385
|
+
|
|
386
|
+
assert.deepEqual(requestParams.body.alias, undefined);
|
|
387
|
+
});
|
|
388
|
+
|
|
368
389
|
it('includes joinCookie and ipver correctly', async () => {
|
|
369
390
|
const locusUrl = 'locusURL';
|
|
370
391
|
const deviceUrl = 'deviceUrl';
|
|
@@ -402,13 +402,18 @@ describe('plugin-meetings', () => {
|
|
|
402
402
|
};
|
|
403
403
|
|
|
404
404
|
const parseLocusJoinSpy = sinon.stub(MeetingUtil, 'parseLocusJoin');
|
|
405
|
-
await MeetingUtil.joinMeeting(meeting, {
|
|
405
|
+
await MeetingUtil.joinMeeting(meeting, {
|
|
406
|
+
reachability: 'reachability',
|
|
407
|
+
roapMessage: 'roapMessage',
|
|
408
|
+
});
|
|
406
409
|
|
|
407
410
|
assert.calledOnce(meeting.meetingRequest.joinMeeting);
|
|
408
411
|
const parameter = meeting.meetingRequest.joinMeeting.getCall(0).args[0];
|
|
409
412
|
|
|
410
413
|
assert.equal(parameter.inviteeAddress, 'meetingJoinUrl');
|
|
411
414
|
assert.equal(parameter.preferTranscoding, true);
|
|
415
|
+
assert.equal(parameter.reachability, 'reachability');
|
|
416
|
+
assert.equal(parameter.roapMessage, 'roapMessage');
|
|
412
417
|
|
|
413
418
|
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
414
419
|
name: 'client.locus.join.request',
|
|
@@ -252,6 +252,12 @@ describe('plugin-meetings', () => {
|
|
|
252
252
|
it('SIP meeting address from excepted domain', () => {
|
|
253
253
|
assert.equal(MeetingInfoUtil.getWebexSite('10019857020@meet.webex.com'), null);
|
|
254
254
|
});
|
|
255
|
+
it('SIP meeting address from excepted domain for IC', () => {
|
|
256
|
+
assert.equal(MeetingInfoUtil.getWebexSite('10019857020@meet-intb.ciscospark.com'), null);
|
|
257
|
+
});
|
|
258
|
+
it('SIP meeting address from webex domain', () => {
|
|
259
|
+
assert.equal(MeetingInfoUtil.getWebexSite('10019857020@webex.com'), null);
|
|
260
|
+
});
|
|
255
261
|
it('invalid domain', () => {
|
|
256
262
|
assert.equal(MeetingInfoUtil.getWebexSite('invaliddomain'), null);
|
|
257
263
|
});
|