@webex/plugin-meetings 2.30.1 → 2.30.2

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.
@@ -3,11 +3,11 @@ import sinon from 'sinon';
3
3
  import {cloneDeep} from 'lodash';
4
4
  import {assert} from '@webex/test-helper-chai';
5
5
  import MockWebex from '@webex/test-helper-mock-webex';
6
-
7
6
  import Meetings from '@webex/plugin-meetings';
8
7
  import LocusInfo from '@webex/plugin-meetings/src/locus-info';
9
8
  import SelfUtils from '@webex/plugin-meetings/src/locus-info/selfUtils';
10
9
  import InfoUtils from '@webex/plugin-meetings/src/locus-info/infoUtils';
10
+ import EmbeddedAppsUtils from '@webex/plugin-meetings/src/locus-info/embeddedAppsUtils';
11
11
  import LocusDeltaParser from '@webex/plugin-meetings/src/locus-info/parser';
12
12
 
13
13
  import {
@@ -15,28 +15,34 @@ import {
15
15
  RECORDING_STATE,
16
16
  LOCUSEVENT,
17
17
  EVENTS,
18
- DISPLAY_HINTS
18
+ DISPLAY_HINTS,
19
19
  } from '../../../../src/constants';
20
20
 
21
21
  import {self, selfWithInactivity} from './selfConstant';
22
22
 
23
23
  describe('plugin-meetings', () => {
24
24
  describe('LocusInfo index', () => {
25
- const updateMeeting = () => {};
25
+ let mockMeeting;
26
+ const updateMeeting = (object) => {
27
+ if (mockMeeting && object && Object.keys(object).length) {
28
+ Object.keys(object).forEach((key) => {
29
+ mockMeeting[key] = object[key];
30
+ });
31
+ }
32
+ };
26
33
  const locus = {};
27
- const meetingId = 'meedingId';
34
+ const meetingId = 'meetingId';
28
35
  let locusInfo;
29
36
 
30
37
  const webex = new MockWebex({
31
38
  children: {
32
- meetings: Meetings
33
- }
39
+ meetings: Meetings,
40
+ },
34
41
  });
35
42
 
36
43
  beforeEach(() => {
37
- locusInfo = new LocusInfo(
38
- updateMeeting, webex, meetingId
39
- );
44
+ mockMeeting = {};
45
+ locusInfo = new LocusInfo(updateMeeting, webex, meetingId);
40
46
 
41
47
  locusInfo.init(locus);
42
48
 
@@ -49,9 +55,9 @@ describe('plugin-meetings', () => {
49
55
  isLocked: false,
50
56
  displayHints: {
51
57
  joined: ['ROSTER_IN_MEETING', 'LOCK_STATUS_UNLOCKED'],
52
- moderator: []
53
- }
54
- }
58
+ moderator: [],
59
+ },
60
+ },
55
61
  };
56
62
  });
57
63
 
@@ -67,14 +73,14 @@ describe('plugin-meetings', () => {
67
73
  paused: false,
68
74
  meta: {
69
75
  lastModified: 'TODAY',
70
- modifiedBy: 'George Kittle'
71
- }
76
+ modifiedBy: 'George Kittle',
77
+ },
72
78
  },
73
79
  shareControl: {},
74
80
  transcribe: {},
75
81
  meetingContainer: {
76
- meetingContainerUrl: 'http://new-url.com'
77
- }
82
+ meetingContainerUrl: 'http://new-url.com',
83
+ },
78
84
  };
79
85
  });
80
86
 
@@ -106,25 +112,28 @@ describe('plugin-meetings', () => {
106
112
  paused: false,
107
113
  meta: {
108
114
  lastModified: 'TODAY',
109
- modifiedBy: 'George Kittle'
110
- }
115
+ modifiedBy: 'George Kittle',
116
+ },
111
117
  },
112
118
  shareControl: {},
113
- transcribe: {}
119
+ transcribe: {},
114
120
  };
115
121
  locusInfo.emitScoped = sinon.stub();
116
122
  locusInfo.updateControls(newControls);
117
123
 
118
- assert.calledWith(locusInfo.emitScoped, {
119
- file: 'locus-info',
120
- function: 'updateControls'
121
- },
122
- LOCUSINFO.EVENTS.CONTROLS_RECORDING_UPDATED,
123
- {
124
- state: RECORDING_STATE.IDLE,
125
- modifiedBy: 'George Kittle',
126
- lastModified: 'TODAY'
127
- });
124
+ assert.calledWith(
125
+ locusInfo.emitScoped,
126
+ {
127
+ file: 'locus-info',
128
+ function: 'updateControls',
129
+ },
130
+ LOCUSINFO.EVENTS.CONTROLS_RECORDING_UPDATED,
131
+ {
132
+ state: RECORDING_STATE.IDLE,
133
+ modifiedBy: 'George Kittle',
134
+ lastModified: 'TODAY',
135
+ }
136
+ );
128
137
  });
129
138
 
130
139
  it('should update the recording state to `RECORDING`', () => {
@@ -136,26 +145,29 @@ describe('plugin-meetings', () => {
136
145
  paused: false,
137
146
  meta: {
138
147
  lastModified: 'TODAY',
139
- modifiedBy: 'George Kittle'
140
- }
148
+ modifiedBy: 'George Kittle',
149
+ },
141
150
  },
142
151
  shareControl: {},
143
- transcribe: {}
152
+ transcribe: {},
144
153
  };
145
154
  newControls.record.recording = true;
146
155
  locusInfo.emitScoped = sinon.stub();
147
156
  locusInfo.updateControls(newControls);
148
157
 
149
- assert.calledWith(locusInfo.emitScoped, {
150
- file: 'locus-info',
151
- function: 'updateControls'
152
- },
153
- LOCUSINFO.EVENTS.CONTROLS_RECORDING_UPDATED,
154
- {
155
- state: RECORDING_STATE.RECORDING,
156
- modifiedBy: 'George Kittle',
157
- lastModified: 'TODAY'
158
- });
158
+ assert.calledWith(
159
+ locusInfo.emitScoped,
160
+ {
161
+ file: 'locus-info',
162
+ function: 'updateControls',
163
+ },
164
+ LOCUSINFO.EVENTS.CONTROLS_RECORDING_UPDATED,
165
+ {
166
+ state: RECORDING_STATE.RECORDING,
167
+ modifiedBy: 'George Kittle',
168
+ lastModified: 'TODAY',
169
+ }
170
+ );
159
171
  });
160
172
 
161
173
  it('should update the recording state to `PAUSED`', () => {
@@ -168,26 +180,29 @@ describe('plugin-meetings', () => {
168
180
  paused: false,
169
181
  meta: {
170
182
  lastModified: 'TODAY',
171
- modifiedBy: 'George Kittle'
172
- }
183
+ modifiedBy: 'George Kittle',
184
+ },
173
185
  },
174
186
  shareControl: {},
175
- transcribe: {}
187
+ transcribe: {},
176
188
  };
177
189
  newControls.record.paused = true;
178
190
  newControls.record.recording = true;
179
191
  locusInfo.updateControls(newControls);
180
192
 
181
- assert.calledWith(locusInfo.emitScoped, {
182
- file: 'locus-info',
183
- function: 'updateControls'
184
- },
185
- LOCUSINFO.EVENTS.CONTROLS_RECORDING_UPDATED,
186
- {
187
- state: RECORDING_STATE.PAUSED,
188
- modifiedBy: 'George Kittle',
189
- lastModified: 'TODAY'
190
- });
193
+ assert.calledWith(
194
+ locusInfo.emitScoped,
195
+ {
196
+ file: 'locus-info',
197
+ function: 'updateControls',
198
+ },
199
+ LOCUSINFO.EVENTS.CONTROLS_RECORDING_UPDATED,
200
+ {
201
+ state: RECORDING_STATE.PAUSED,
202
+ modifiedBy: 'George Kittle',
203
+ lastModified: 'TODAY',
204
+ }
205
+ );
191
206
  });
192
207
 
193
208
  it('should update the recording state to `RESUMED`', () => {
@@ -200,27 +215,30 @@ describe('plugin-meetings', () => {
200
215
  paused: true,
201
216
  meta: {
202
217
  lastModified: 'TODAY',
203
- modifiedBy: 'George Kittle'
204
- }
218
+ modifiedBy: 'George Kittle',
219
+ },
205
220
  },
206
221
  shareControl: {},
207
- transcribe: {}
222
+ transcribe: {},
208
223
  };
209
224
  // there must be a recording to be paused/resumed
210
225
  newControls.record.recording = true;
211
226
  newControls.record.paused = false;
212
227
  locusInfo.updateControls(newControls);
213
228
 
214
- assert.calledWith(locusInfo.emitScoped, {
215
- file: 'locus-info',
216
- function: 'updateControls'
217
- },
218
- LOCUSINFO.EVENTS.CONTROLS_RECORDING_UPDATED,
219
- {
220
- state: RECORDING_STATE.RESUMED,
221
- modifiedBy: 'George Kittle',
222
- lastModified: 'TODAY'
223
- });
229
+ assert.calledWith(
230
+ locusInfo.emitScoped,
231
+ {
232
+ file: 'locus-info',
233
+ function: 'updateControls',
234
+ },
235
+ LOCUSINFO.EVENTS.CONTROLS_RECORDING_UPDATED,
236
+ {
237
+ state: RECORDING_STATE.RESUMED,
238
+ modifiedBy: 'George Kittle',
239
+ lastModified: 'TODAY',
240
+ }
241
+ );
224
242
  });
225
243
 
226
244
  it('should update the recording state to `IDLE` even if `pause`status changes', () => {
@@ -233,26 +251,29 @@ describe('plugin-meetings', () => {
233
251
  paused: true,
234
252
  meta: {
235
253
  lastModified: 'TODAY',
236
- modifiedBy: 'George Kittle'
237
- }
254
+ modifiedBy: 'George Kittle',
255
+ },
238
256
  },
239
257
  shareControl: {},
240
- transcribe: {}
258
+ transcribe: {},
241
259
  };
242
260
  newControls.record.recording = false;
243
261
  newControls.record.paused = false;
244
262
  locusInfo.updateControls(newControls);
245
263
 
246
- assert.calledWith(locusInfo.emitScoped, {
247
- file: 'locus-info',
248
- function: 'updateControls'
249
- },
250
- LOCUSINFO.EVENTS.CONTROLS_RECORDING_UPDATED,
251
- {
252
- state: RECORDING_STATE.IDLE,
253
- modifiedBy: 'George Kittle',
254
- lastModified: 'TODAY'
255
- });
264
+ assert.calledWith(
265
+ locusInfo.emitScoped,
266
+ {
267
+ file: 'locus-info',
268
+ function: 'updateControls',
269
+ },
270
+ LOCUSINFO.EVENTS.CONTROLS_RECORDING_UPDATED,
271
+ {
272
+ state: RECORDING_STATE.IDLE,
273
+ modifiedBy: 'George Kittle',
274
+ lastModified: 'TODAY',
275
+ }
276
+ );
256
277
  });
257
278
 
258
279
  it('should update the transcript state', () => {
@@ -265,28 +286,32 @@ describe('plugin-meetings', () => {
265
286
  paused: true,
266
287
  meta: {
267
288
  lastModified: 'TODAY',
268
- modifiedBy: 'George Kittle'
269
- }
289
+ modifiedBy: 'George Kittle',
290
+ },
270
291
  },
271
292
  shareControl: {},
272
293
  transcribe: {
273
294
  transcribing: false,
274
- caption: false
275
- }
295
+ caption: false,
296
+ },
276
297
  };
277
298
  newControls.transcribe.transcribing = true;
278
299
  newControls.transcribe.caption = true;
279
300
 
280
301
  locusInfo.updateControls(newControls);
281
302
 
282
- assert.calledWith(locusInfo.emitScoped, {
283
- file: 'locus-info',
284
- function: 'updateControls'
285
- },
286
- LOCUSINFO.EVENTS.CONTROLS_MEETING_TRANSCRIBE_UPDATED,
287
- {
288
- transcribing: true, caption: true
289
- });
303
+ assert.calledWith(
304
+ locusInfo.emitScoped,
305
+ {
306
+ file: 'locus-info',
307
+ function: 'updateControls',
308
+ },
309
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_TRANSCRIBE_UPDATED,
310
+ {
311
+ transcribing: true,
312
+ caption: true,
313
+ }
314
+ );
290
315
  });
291
316
 
292
317
  it('should update the meetingContainerURL from null', () => {
@@ -297,12 +322,15 @@ describe('plugin-meetings', () => {
297
322
  locusInfo.emitScoped = sinon.stub();
298
323
  locusInfo.updateControls(newControls);
299
324
 
300
- assert.calledWith(locusInfo.emitScoped, {
301
- file: 'locus-info',
302
- function: 'updateControls'
303
- },
304
- LOCUSINFO.EVENTS.CONTROLS_MEETING_CONTAINER_UPDATED,
305
- {meetingContainerUrl: 'http://new-url.com'});
325
+ assert.calledWith(
326
+ locusInfo.emitScoped,
327
+ {
328
+ file: 'locus-info',
329
+ function: 'updateControls',
330
+ },
331
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_CONTAINER_UPDATED,
332
+ {meetingContainerUrl: 'http://new-url.com'}
333
+ );
306
334
  });
307
335
 
308
336
  it('should update the meetingContainerURL from not null', () => {
@@ -313,12 +341,15 @@ describe('plugin-meetings', () => {
313
341
  locusInfo.emitScoped = sinon.stub();
314
342
  locusInfo.updateControls(newControls);
315
343
 
316
- assert.calledWith(locusInfo.emitScoped, {
317
- file: 'locus-info',
318
- function: 'updateControls'
319
- },
320
- LOCUSINFO.EVENTS.CONTROLS_MEETING_CONTAINER_UPDATED,
321
- {meetingContainerUrl: 'http://new-url.com'});
344
+ assert.calledWith(
345
+ locusInfo.emitScoped,
346
+ {
347
+ file: 'locus-info',
348
+ function: 'updateControls',
349
+ },
350
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_CONTAINER_UPDATED,
351
+ {meetingContainerUrl: 'http://new-url.com'}
352
+ );
322
353
  });
323
354
 
324
355
  it('should update the meetingContainerURL from missing', () => {
@@ -327,12 +358,15 @@ describe('plugin-meetings', () => {
327
358
  locusInfo.emitScoped = sinon.stub();
328
359
  locusInfo.updateControls(newControls);
329
360
 
330
- assert.calledWith(locusInfo.emitScoped, {
331
- file: 'locus-info',
332
- function: 'updateControls'
333
- },
334
- LOCUSINFO.EVENTS.CONTROLS_MEETING_CONTAINER_UPDATED,
335
- {meetingContainerUrl: 'http://new-url.com'});
361
+ assert.calledWith(
362
+ locusInfo.emitScoped,
363
+ {
364
+ file: 'locus-info',
365
+ function: 'updateControls',
366
+ },
367
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_CONTAINER_UPDATED,
368
+ {meetingContainerUrl: 'http://new-url.com'}
369
+ );
336
370
  });
337
371
  });
338
372
 
@@ -343,14 +377,14 @@ describe('plugin-meetings', () => {
343
377
  newParticipants = [
344
378
  {
345
379
  person: {
346
- id: 1234
380
+ id: 1234,
347
381
  },
348
382
  status: {
349
383
  audioStatus: 'testValue',
350
384
  videoSlidesStatus: 'testValue',
351
- videoStatus: 'testValue'
352
- }
353
- }
385
+ videoStatus: 'testValue',
386
+ },
387
+ },
354
388
  ];
355
389
  });
356
390
 
@@ -358,26 +392,27 @@ describe('plugin-meetings', () => {
358
392
  locusInfo.parsedLocus = {
359
393
  controls: {
360
394
  record: {
361
- modifiedBy: '1'
362
- }
395
+ modifiedBy: '1',
396
+ },
363
397
  },
364
398
  self: {
365
399
  selfIdentity: '123',
366
- selfId: '2'
400
+ selfId: '2',
367
401
  },
368
402
  host: {
369
- hostId: '3'
370
- }
403
+ hostId: '3',
404
+ },
371
405
  };
372
406
  locusInfo.emitScoped = sinon.stub();
373
407
  locusInfo.updateParticipants({});
374
408
 
375
409
  // if this assertion fails, double-check the attributes used in
376
410
  // the updateParticipants function in locus-info/index.js
377
- assert.calledWith(locusInfo.emitScoped,
411
+ assert.calledWith(
412
+ locusInfo.emitScoped,
378
413
  {
379
414
  file: 'locus-info',
380
- function: 'updateParticipants'
415
+ function: 'updateParticipants',
381
416
  },
382
417
  EVENTS.LOCUS_INFO_UPDATE_PARTICIPANTS,
383
418
  {
@@ -385,8 +420,9 @@ describe('plugin-meetings', () => {
385
420
  recordingId: '1',
386
421
  selfIdentity: '123',
387
422
  selfId: '2',
388
- hostId: '3'
389
- });
423
+ hostId: '3',
424
+ }
425
+ );
390
426
  // note: in a real use case, recordingId, selfId, and hostId would all be the same
391
427
  // for this specific test, we are double-checking that each of the id's
392
428
  // are being correctly grabbed from locusInfo.parsedLocus within updateParticipants
@@ -434,19 +470,24 @@ describe('plugin-meetings', () => {
434
470
  locusInfo.self = undefined;
435
471
  const selfWithLayoutChanged = cloneDeep(self);
436
472
 
437
- selfWithLayoutChanged.controls.layouts = [{
438
- type: layoutType,
439
- }];
473
+ selfWithLayoutChanged.controls.layouts = [
474
+ {
475
+ type: layoutType,
476
+ },
477
+ ];
440
478
 
441
479
  locusInfo.emitScoped = sinon.stub();
442
480
  locusInfo.updateSelf(selfWithLayoutChanged, []);
443
481
 
444
- assert.calledWith(locusInfo.emitScoped, {
445
- file: 'locus-info',
446
- function: 'updateSelf'
447
- },
448
- LOCUSINFO.EVENTS.CONTROLS_MEETING_LAYOUT_UPDATED,
449
- {layout: layoutType});
482
+ assert.calledWith(
483
+ locusInfo.emitScoped,
484
+ {
485
+ file: 'locus-info',
486
+ function: 'updateSelf',
487
+ },
488
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_LAYOUT_UPDATED,
489
+ {layout: layoutType}
490
+ );
450
491
  });
451
492
 
452
493
  it('should not trigger CONTROLS_MEETING_LAYOUT_UPDATED when the meeting layout controls did not change', () => {
@@ -455,9 +496,11 @@ describe('plugin-meetings', () => {
455
496
  locusInfo.self = undefined;
456
497
  const selfWithLayoutChanged = cloneDeep(self);
457
498
 
458
- selfWithLayoutChanged.controls.layouts = [{
459
- type: layoutType,
460
- }];
499
+ selfWithLayoutChanged.controls.layouts = [
500
+ {
501
+ type: layoutType,
502
+ },
503
+ ];
461
504
 
462
505
  // Set the layout prior to stubbing to validate it does not change.
463
506
  locusInfo.updateSelf(selfWithLayoutChanged, []);
@@ -466,12 +509,15 @@ describe('plugin-meetings', () => {
466
509
 
467
510
  locusInfo.updateSelf(selfWithLayoutChanged, []);
468
511
 
469
- assert.neverCalledWith(locusInfo.emitScoped, {
470
- file: 'locus-info',
471
- function: 'updateSelf'
472
- },
473
- LOCUSINFO.EVENTS.CONTROLS_MEETING_LAYOUT_UPDATED,
474
- {layout: layoutType});
512
+ assert.neverCalledWith(
513
+ locusInfo.emitScoped,
514
+ {
515
+ file: 'locus-info',
516
+ function: 'updateSelf',
517
+ },
518
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_LAYOUT_UPDATED,
519
+ {layout: layoutType}
520
+ );
475
521
  });
476
522
 
477
523
  it('should trigger MEDIA_INACTIVITY on server media inactivity', () => {
@@ -481,12 +527,15 @@ describe('plugin-meetings', () => {
481
527
  locusInfo.emitScoped = sinon.stub();
482
528
  locusInfo.updateSelf(selfWithInactivity, []);
483
529
 
484
- assert.calledWith(locusInfo.emitScoped, {
485
- file: 'locus-info',
486
- function: 'updateSelf'
487
- },
488
- LOCUSINFO.EVENTS.MEDIA_INACTIVITY,
489
- SelfUtils.getMediaStatus(selfWithInactivity.mediaSessions));
530
+ assert.calledWith(
531
+ locusInfo.emitScoped,
532
+ {
533
+ file: 'locus-info',
534
+ function: 'updateSelf',
535
+ },
536
+ LOCUSINFO.EVENTS.MEDIA_INACTIVITY,
537
+ SelfUtils.getMediaStatus(selfWithInactivity.mediaSessions)
538
+ );
490
539
  });
491
540
 
492
541
  it('should trigger SELF_REMOTE_MUTE_STATUS_UPDATED when muted on entry', () => {
@@ -500,24 +549,30 @@ describe('plugin-meetings', () => {
500
549
  locusInfo.emitScoped = sinon.stub();
501
550
  locusInfo.updateSelf(selfWithMutedByOthers, []);
502
551
 
503
- assert.calledWith(locusInfo.emitScoped, {
504
- file: 'locus-info',
505
- function: 'updateSelf'
506
- },
507
- LOCUSINFO.EVENTS.SELF_REMOTE_MUTE_STATUS_UPDATED,
508
- {muted: true, unmuteAllowed: true});
552
+ assert.calledWith(
553
+ locusInfo.emitScoped,
554
+ {
555
+ file: 'locus-info',
556
+ function: 'updateSelf',
557
+ },
558
+ LOCUSINFO.EVENTS.SELF_REMOTE_MUTE_STATUS_UPDATED,
559
+ {muted: true, unmuteAllowed: true}
560
+ );
509
561
 
510
562
  // but sometimes "previous self" is defined, but without controls.audio.muted, so we test this here:
511
563
  locusInfo.self = cloneDeep(self);
512
564
  locusInfo.self.controls.audio = {};
513
565
 
514
566
  locusInfo.updateSelf(selfWithMutedByOthers, []);
515
- assert.calledWith(locusInfo.emitScoped, {
516
- file: 'locus-info',
517
- function: 'updateSelf'
518
- },
519
- LOCUSINFO.EVENTS.SELF_REMOTE_MUTE_STATUS_UPDATED,
520
- {muted: true, unmuteAllowed: true});
567
+ assert.calledWith(
568
+ locusInfo.emitScoped,
569
+ {
570
+ file: 'locus-info',
571
+ function: 'updateSelf',
572
+ },
573
+ LOCUSINFO.EVENTS.SELF_REMOTE_MUTE_STATUS_UPDATED,
574
+ {muted: true, unmuteAllowed: true}
575
+ );
521
576
  });
522
577
 
523
578
  it('should not trigger SELF_REMOTE_MUTE_STATUS_UPDATED when not muted on entry', () => {
@@ -568,12 +623,15 @@ describe('plugin-meetings', () => {
568
623
  locusInfo.emitScoped = sinon.stub();
569
624
  locusInfo.updateSelf(selfWithMutedByOthers, []);
570
625
 
571
- assert.calledWith(locusInfo.emitScoped, {
572
- file: 'locus-info',
573
- function: 'updateSelf'
574
- },
575
- LOCUSINFO.EVENTS.SELF_REMOTE_MUTE_STATUS_UPDATED,
576
- {muted: true, unmuteAllowed: true});
626
+ assert.calledWith(
627
+ locusInfo.emitScoped,
628
+ {
629
+ file: 'locus-info',
630
+ function: 'updateSelf',
631
+ },
632
+ LOCUSINFO.EVENTS.SELF_REMOTE_MUTE_STATUS_UPDATED,
633
+ {muted: true, unmuteAllowed: true}
634
+ );
577
635
  });
578
636
 
579
637
  it('should trigger SELF_REMOTE_MUTE_STATUS_UPDATED if muted and disallowUnmute changed', () => {
@@ -588,12 +646,15 @@ describe('plugin-meetings', () => {
588
646
  locusInfo.emitScoped = sinon.stub();
589
647
  locusInfo.updateSelf(selfWithMutedByOthersAndDissalowUnmute, []);
590
648
 
591
- assert.calledWith(locusInfo.emitScoped, {
592
- file: 'locus-info',
593
- function: 'updateSelf'
594
- },
595
- LOCUSINFO.EVENTS.SELF_REMOTE_MUTE_STATUS_UPDATED,
596
- {muted: true, unmuteAllowed: false});
649
+ assert.calledWith(
650
+ locusInfo.emitScoped,
651
+ {
652
+ file: 'locus-info',
653
+ function: 'updateSelf',
654
+ },
655
+ LOCUSINFO.EVENTS.SELF_REMOTE_MUTE_STATUS_UPDATED,
656
+ {muted: true, unmuteAllowed: false}
657
+ );
597
658
 
598
659
  // now change only disallowUnmute
599
660
  const selfWithMutedByOthers = cloneDeep(self);
@@ -603,12 +664,15 @@ describe('plugin-meetings', () => {
603
664
 
604
665
  locusInfo.updateSelf(selfWithMutedByOthers, []);
605
666
 
606
- assert.calledWith(locusInfo.emitScoped, {
607
- file: 'locus-info',
608
- function: 'updateSelf'
609
- },
610
- LOCUSINFO.EVENTS.SELF_REMOTE_MUTE_STATUS_UPDATED,
611
- {muted: true, unmuteAllowed: true});
667
+ assert.calledWith(
668
+ locusInfo.emitScoped,
669
+ {
670
+ file: 'locus-info',
671
+ function: 'updateSelf',
672
+ },
673
+ LOCUSINFO.EVENTS.SELF_REMOTE_MUTE_STATUS_UPDATED,
674
+ {muted: true, unmuteAllowed: true}
675
+ );
612
676
  });
613
677
 
614
678
  it('should trigger LOCAL_UNMUTE_REQUIRED on localAudioUnmuteRequired', () => {
@@ -622,15 +686,18 @@ describe('plugin-meetings', () => {
622
686
  locusInfo.emitScoped = sinon.stub();
623
687
  locusInfo.updateSelf(selfWithLocalUnmuteRequired, []);
624
688
 
625
- assert.calledWith(locusInfo.emitScoped, {
626
- file: 'locus-info',
627
- function: 'updateSelf'
628
- },
629
- LOCUSINFO.EVENTS.LOCAL_UNMUTE_REQUIRED,
630
- {
631
- muted: false,
632
- unmuteAllowed: true
633
- });
689
+ assert.calledWith(
690
+ locusInfo.emitScoped,
691
+ {
692
+ file: 'locus-info',
693
+ function: 'updateSelf',
694
+ },
695
+ LOCUSINFO.EVENTS.LOCAL_UNMUTE_REQUIRED,
696
+ {
697
+ muted: false,
698
+ unmuteAllowed: true,
699
+ }
700
+ );
634
701
  });
635
702
 
636
703
  it('should trigger LOCAL_UNMUTE_REQUESTED when receiving requestedToUnmute=true', () => {
@@ -643,12 +710,15 @@ describe('plugin-meetings', () => {
643
710
  locusInfo.emitScoped = sinon.stub();
644
711
  locusInfo.updateSelf(selfWithRequestedToUnmute, []);
645
712
 
646
- assert.calledWith(locusInfo.emitScoped, {
647
- file: 'locus-info',
648
- function: 'updateSelf'
649
- },
650
- LOCUSINFO.EVENTS.LOCAL_UNMUTE_REQUESTED,
651
- {});
713
+ assert.calledWith(
714
+ locusInfo.emitScoped,
715
+ {
716
+ file: 'locus-info',
717
+ function: 'updateSelf',
718
+ },
719
+ LOCUSINFO.EVENTS.LOCAL_UNMUTE_REQUESTED,
720
+ {}
721
+ );
652
722
 
653
723
  // now change requestedToUnmute back to false -> it should NOT trigger LOCAL_UNMUTE_REQUESTED
654
724
  const selfWithoutRequestedToUnmute = cloneDeep(selfWithRequestedToUnmute);
@@ -658,15 +728,17 @@ describe('plugin-meetings', () => {
658
728
  locusInfo.emitScoped.resetHistory();
659
729
  locusInfo.updateSelf(selfWithoutRequestedToUnmute, []);
660
730
 
661
- assert.neverCalledWith(locusInfo.emitScoped, {
662
- file: 'locus-info',
663
- function: 'updateSelf'
664
- },
665
- LOCUSINFO.EVENTS.LOCAL_UNMUTE_REQUESTED,
666
- {});
731
+ assert.neverCalledWith(
732
+ locusInfo.emitScoped,
733
+ {
734
+ file: 'locus-info',
735
+ function: 'updateSelf',
736
+ },
737
+ LOCUSINFO.EVENTS.LOCAL_UNMUTE_REQUESTED,
738
+ {}
739
+ );
667
740
  });
668
741
 
669
-
670
742
  it('should trigger SELF_OBSERVING when moving meeting to DX', () => {
671
743
  locusInfo.self = self;
672
744
  const selfInitiatedMove = cloneDeep(self);
@@ -686,11 +758,14 @@ describe('plugin-meetings', () => {
686
758
 
687
759
  locusInfo.updateSelf(selfAfterDxJoins, []);
688
760
 
689
- assert.calledWith(locusInfo.emitScoped, {
690
- file: 'locus-info',
691
- function: 'updateSelf'
692
- },
693
- LOCUSINFO.EVENTS.SELF_OBSERVING);
761
+ assert.calledWith(
762
+ locusInfo.emitScoped,
763
+ {
764
+ file: 'locus-info',
765
+ function: 'updateSelf',
766
+ },
767
+ LOCUSINFO.EVENTS.SELF_OBSERVING
768
+ );
694
769
  });
695
770
  });
696
771
 
@@ -704,8 +779,8 @@ describe('plugin-meetings', () => {
704
779
  meetingInfo = {
705
780
  displayHints: {
706
781
  joined: ['ROSTER_IN_MEETING', 'LOCK_STATUS_UNLOCKED'],
707
- moderator: []
708
- }
782
+ moderator: [],
783
+ },
709
784
  };
710
785
  getInfosSpy = sinon.spy(InfoUtils, 'getInfos');
711
786
  getRolesSpy = sinon.spy(SelfUtils, 'getRoles');
@@ -731,33 +806,42 @@ describe('plugin-meetings', () => {
731
806
  locusInfo.emitScoped = sinon.stub();
732
807
  locusInfo.updateMeetingInfo(meetingInfoLocked, self);
733
808
 
734
- assert.calledWith(locusInfo.emitScoped, {
735
- file: 'locus-info',
736
- function: 'updateMeetingInfo'
737
- },
738
- LOCUSINFO.EVENTS.MEETING_LOCKED,
739
- meetingInfoLocked);
809
+ assert.calledWith(
810
+ locusInfo.emitScoped,
811
+ {
812
+ file: 'locus-info',
813
+ function: 'updateMeetingInfo',
814
+ },
815
+ LOCUSINFO.EVENTS.MEETING_LOCKED,
816
+ meetingInfoLocked
817
+ );
740
818
 
741
819
  // now unlock the meeting and verify that we get the right event
742
820
  const meetingInfoUnlocked = cloneDeep(meetingInfo); // meetingInfo already is "unlocked"
743
821
 
744
822
  locusInfo.updateMeetingInfo(meetingInfoUnlocked, self);
745
823
 
746
- assert.calledWith(locusInfo.emitScoped, {
747
- file: 'locus-info',
748
- function: 'updateMeetingInfo'
749
- },
750
- LOCUSINFO.EVENTS.MEETING_UNLOCKED,
751
- meetingInfoUnlocked);
824
+ assert.calledWith(
825
+ locusInfo.emitScoped,
826
+ {
827
+ file: 'locus-info',
828
+ function: 'updateMeetingInfo',
829
+ },
830
+ LOCUSINFO.EVENTS.MEETING_UNLOCKED,
831
+ meetingInfoUnlocked
832
+ );
752
833
  });
753
834
 
754
835
  const checkMeetingInfoUpdatedCalled = (expected) => {
755
- const expectedArgs = [locusInfo.emitScoped, {
756
- file: 'locus-info',
757
- function: 'updateMeetingInfo'
758
- },
759
- LOCUSINFO.EVENTS.MEETING_INFO_UPDATED,
760
- {info: locusInfo.parsedLocus.info, self}];
836
+ const expectedArgs = [
837
+ locusInfo.emitScoped,
838
+ {
839
+ file: 'locus-info',
840
+ function: 'updateMeetingInfo',
841
+ },
842
+ LOCUSINFO.EVENTS.MEETING_INFO_UPDATED,
843
+ {info: locusInfo.parsedLocus.info, self},
844
+ ];
761
845
 
762
846
  if (expected) {
763
847
  assert.calledWith(...expectedArgs);
@@ -803,17 +887,14 @@ describe('plugin-meetings', () => {
803
887
  locusInfo.updateMeetingInfo(initialInfo, self);
804
888
 
805
889
  assert.calledWith(getRolesSpy, self);
806
- assert.calledWith(
807
- getInfosSpy,
808
- parsedLocusInfo, initialInfo, ['PRESENTER']
809
- );
890
+ assert.calledWith(getInfosSpy, parsedLocusInfo, initialInfo, ['PRESENTER']);
810
891
  });
811
892
 
812
893
  it('gets roles from parsedLocus if self not passed in', () => {
813
894
  const initialInfo = cloneDeep(meetingInfo);
814
895
 
815
896
  locusInfo.parsedLocus.self = {
816
- roles: ['MODERATOR', 'COHOST']
897
+ roles: ['MODERATOR', 'COHOST'],
817
898
  };
818
899
 
819
900
  const parsedLocusInfo = cloneDeep(locusInfo.parsedLocus.info);
@@ -821,36 +902,38 @@ describe('plugin-meetings', () => {
821
902
  locusInfo.updateMeetingInfo(initialInfo);
822
903
  assert.calledWith(isJoinedSpy, locusInfo.parsedLocus.self);
823
904
  assert.neverCalledWith(getRolesSpy, self);
824
- assert.calledWith(
825
- getInfosSpy,
826
- parsedLocusInfo, initialInfo, ['MODERATOR', 'COHOST']
827
- );
905
+ assert.calledWith(getInfosSpy, parsedLocusInfo, initialInfo, ['MODERATOR', 'COHOST']);
828
906
  });
829
907
  });
830
908
 
831
909
  describe('#updateEmbeddedApps()', () => {
832
- const newEmbeddedApps = [{
833
- url: 'https://hecate-b.wbx2.com/apps/api/v1/locus/7a4994a7',
834
- sequence: 138849877016800000,
835
- appId: 'Y2lzY29zcGFyazovL3VzL0FQUExJQ0FUSU9OLzQxODc1MGQ0LTM3ZDctNGY2MC1hOWE3LWEwZTE1NDFhNjRkNg',
836
- instanceInfo: {
837
- appInstanceUrl: 'https://webex.sli.do/participant/event/mFKKjcYxzx9h31eyWgngFS?clusterId=eu1',
838
- externalAppInstanceUrl: '',
839
- title: 'Active session'
910
+ const newEmbeddedApps = [
911
+ {
912
+ url: 'https://hecate-b.wbx2.com/apps/api/v1/locus/7a4994a7',
913
+ sequence: 138849877016800000,
914
+ appId:
915
+ 'Y2lzY29zcGFyazovL3VzL0FQUExJQ0FUSU9OLzQxODc1MGQ0LTM3ZDctNGY2MC1hOWE3LWEwZTE1NDFhNjRkNg',
916
+ instanceInfo: {
917
+ appInstanceUrl:
918
+ 'https://webex.sli.do/participant/event/mFKKjcYxzx9h31eyWgngFS?clusterId=eu1',
919
+ externalAppInstanceUrl: '',
920
+ title: 'Active session',
921
+ },
922
+ state: 'STARTED',
923
+ lastModified: '2022-10-13T21:01:41.680Z',
840
924
  },
841
- state: 'STARTED',
842
- lastModified: '2022-10-13T21:01:41.680Z'
843
- }];
925
+ ];
844
926
 
845
- it('updates the embeddedApps object', () => {
846
- const prev = locusInfo.embeddedApps;
927
+ it('properly updates the meeting embeddedApps', () => {
928
+ const prev = mockMeeting.embeddedApps;
847
929
 
848
930
  locusInfo.updateEmbeddedApps(newEmbeddedApps);
849
931
 
850
- assert.notEqual(locusInfo.embeddedApps, prev);
932
+ assert.notEqual(mockMeeting.embeddedApps, prev);
933
+ assert.isNotNull(mockMeeting.embeddedApps?.[0].type);
851
934
  });
852
935
 
853
- it('does not emit EMBEDDED_APPS_UPDATED when apps didn\'t change', () => {
936
+ it("does not emit EMBEDDED_APPS_UPDATED when apps didn't change", () => {
854
937
  locusInfo.updateEmbeddedApps(newEmbeddedApps);
855
938
 
856
939
  locusInfo.emitScoped = sinon.stub();
@@ -870,15 +953,19 @@ describe('plugin-meetings', () => {
870
953
  const clonedApps = cloneDeep(newEmbeddedApps);
871
954
 
872
955
  clonedApps[0].state = 'STOPPED';
956
+ const expectedApps = EmbeddedAppsUtils.parse(clonedApps);
873
957
 
874
958
  locusInfo.updateEmbeddedApps(clonedApps);
875
959
 
876
- assert.calledWith(locusInfo.emitScoped, {
877
- file: 'locus-info',
878
- function: 'updateEmbeddedApps'
879
- },
880
- LOCUSINFO.EVENTS.EMBEDDED_APPS_UPDATED,
881
- clonedApps);
960
+ assert.calledWith(
961
+ locusInfo.emitScoped,
962
+ {
963
+ file: 'locus-info',
964
+ function: 'updateEmbeddedApps',
965
+ },
966
+ LOCUSINFO.EVENTS.EMBEDDED_APPS_UPDATED,
967
+ expectedApps
968
+ );
882
969
  });
883
970
  });
884
971
 
@@ -894,7 +981,7 @@ describe('plugin-meetings', () => {
894
981
 
895
982
  fakeLocus = {
896
983
  meeting: true,
897
- participants: true
984
+ participants: true,
898
985
  };
899
986
  });
900
987
 
@@ -903,13 +990,12 @@ describe('plugin-meetings', () => {
903
990
  sandbox = null;
904
991
  });
905
992
 
906
-
907
993
  it('handles locus delta events', () => {
908
994
  sandbox.stub(locusInfo, 'handleLocusDelta');
909
995
 
910
996
  const data = {
911
997
  eventType: LOCUSEVENT.DIFFERENCE,
912
- locus: fakeLocus
998
+ locus: fakeLocus,
913
999
  };
914
1000
 
915
1001
  locusInfo.parse(fakeMeeting, data);
@@ -917,13 +1003,12 @@ describe('plugin-meetings', () => {
917
1003
  assert.calledWith(locusInfo.handleLocusDelta, fakeLocus, fakeMeeting);
918
1004
  });
919
1005
 
920
-
921
1006
  it('should queue delta event with internal locus parser', () => {
922
1007
  sandbox.stub(locusParser, 'onDeltaEvent');
923
1008
 
924
1009
  const data = {
925
1010
  eventType: LOCUSEVENT.DIFFERENCE,
926
- locus: fakeLocus
1011
+ locus: fakeLocus,
927
1012
  };
928
1013
 
929
1014
  locusInfo.parse(fakeMeeting, data);
@@ -932,7 +1017,6 @@ describe('plugin-meetings', () => {
932
1017
  assert.calledWith(locusParser.onDeltaEvent, fakeLocus);
933
1018
  });
934
1019
 
935
-
936
1020
  it('should assign a function to onDeltaAction', () => {
937
1021
  sandbox.stub(locusParser, 'onDeltaEvent');
938
1022
  assert.isNull(locusParser.onDeltaAction);
@@ -942,7 +1026,6 @@ describe('plugin-meetings', () => {
942
1026
  assert.isFunction(locusParser.onDeltaAction);
943
1027
  });
944
1028
 
945
-
946
1029
  it('onFullLocus() updates the working-copy of locus parser', () => {
947
1030
  const eventType = 'fakeEvent';
948
1031
 
@@ -957,7 +1040,6 @@ describe('plugin-meetings', () => {
957
1040
  assert.equal(fakeLocus, locusParser.workingCopy);
958
1041
  });
959
1042
 
960
-
961
1043
  it('onDeltaAction applies locus delta data to meeting', () => {
962
1044
  const action = 'fake action';
963
1045
  const parsedLoci = 'fake loci';
@@ -971,13 +1053,12 @@ describe('plugin-meetings', () => {
971
1053
  assert.calledWith(locusInfo.applyLocusDeltaData, action, parsedLoci, fakeMeeting);
972
1054
  });
973
1055
 
974
-
975
1056
  it('applyLocusDeltaData handles USE_INCOMING action correctly', () => {
976
1057
  const {USE_INCOMING} = LocusDeltaParser.loci;
977
1058
  const meeting = {
978
1059
  locusInfo: {
979
- onDeltaLocus: sandbox.stub()
980
- }
1060
+ onDeltaLocus: sandbox.stub(),
1061
+ },
981
1062
  };
982
1063
 
983
1064
  locusInfo.applyLocusDeltaData(USE_INCOMING, fakeLocus, meeting);
@@ -985,16 +1066,15 @@ describe('plugin-meetings', () => {
985
1066
  assert.calledWith(meeting.locusInfo.onDeltaLocus, fakeLocus);
986
1067
  });
987
1068
 
988
-
989
1069
  it('applyLocusDeltaData gets full locus on DESYNC action', () => {
990
1070
  const {DESYNC} = LocusDeltaParser.loci;
991
1071
  const meeting = {
992
1072
  meetingRequest: {
993
- getFullLocus: sandbox.stub().resolves(true)
1073
+ getFullLocus: sandbox.stub().resolves(true),
994
1074
  },
995
1075
  locusInfo: {
996
- onFullLocus: sandbox.stub()
997
- }
1076
+ onFullLocus: sandbox.stub(),
1077
+ },
998
1078
  };
999
1079
 
1000
1080
  locusInfo.locusParser.resume = sandbox.stub();
@@ -1007,9 +1087,9 @@ describe('plugin-meetings', () => {
1007
1087
  const {DESYNC} = LocusDeltaParser.loci;
1008
1088
  const meeting = {
1009
1089
  meetingRequest: {
1010
- getFullLocus: sandbox.stub().resolves({body: true})
1090
+ getFullLocus: sandbox.stub().resolves({body: true}),
1011
1091
  },
1012
- locusInfo
1092
+ locusInfo,
1013
1093
  };
1014
1094
 
1015
1095
  locusInfo.onFullLocus = sandbox.stub();
@@ -1037,29 +1117,34 @@ describe('plugin-meetings', () => {
1037
1117
  locusInfo.parsedLocus.fullState.type = 'SIP_BRIDGE';
1038
1118
  locusInfo.handleOneOnOneEvent('locus.participant_declined');
1039
1119
 
1040
- assert.calledWith(locusInfo.emitScoped, {
1041
- file: 'locus-info',
1042
- function: 'handleOneonOneEvent'
1043
- },
1044
- 'REMOTE_RESPONSE',
1045
- {
1046
- remoteDeclined: true,
1047
- remoteAnswered: false
1048
- });
1049
-
1120
+ assert.calledWith(
1121
+ locusInfo.emitScoped,
1122
+ {
1123
+ file: 'locus-info',
1124
+ function: 'handleOneonOneEvent',
1125
+ },
1126
+ 'REMOTE_RESPONSE',
1127
+ {
1128
+ remoteDeclined: true,
1129
+ remoteAnswered: false,
1130
+ }
1131
+ );
1050
1132
 
1051
1133
  locusInfo.parsedLocus.fullState.type = 'SIP_BRIDGE';
1052
1134
  locusInfo.handleOneOnOneEvent('locus.participant_joined');
1053
1135
 
1054
- assert.calledWith(locusInfo.emitScoped, {
1055
- file: 'locus-info',
1056
- function: 'handleOneonOneEvent'
1057
- },
1058
- 'REMOTE_RESPONSE',
1059
- {
1060
- remoteDeclined: false,
1061
- remoteAnswered: true
1062
- });
1136
+ assert.calledWith(
1137
+ locusInfo.emitScoped,
1138
+ {
1139
+ file: 'locus-info',
1140
+ function: 'handleOneonOneEvent',
1141
+ },
1142
+ 'REMOTE_RESPONSE',
1143
+ {
1144
+ remoteDeclined: false,
1145
+ remoteAnswered: true,
1146
+ }
1147
+ );
1063
1148
  });
1064
1149
  });
1065
1150
  });