@webex/plugin-meetings 3.9.0-next.2 → 3.9.0-next.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/constants.js +2 -0
  4. package/dist/constants.js.map +1 -1
  5. package/dist/interpretation/index.js +1 -1
  6. package/dist/interpretation/siLanguage.js +1 -1
  7. package/dist/locus-info/index.js +38 -10
  8. package/dist/locus-info/index.js.map +1 -1
  9. package/dist/locus-info/parser.js +4 -1
  10. package/dist/locus-info/parser.js.map +1 -1
  11. package/dist/media/properties.js +53 -5
  12. package/dist/media/properties.js.map +1 -1
  13. package/dist/meeting/in-meeting-actions.js +2 -0
  14. package/dist/meeting/in-meeting-actions.js.map +1 -1
  15. package/dist/meeting/index.js +189 -122
  16. package/dist/meeting/index.js.map +1 -1
  17. package/dist/meeting/muteState.js +2 -5
  18. package/dist/meeting/muteState.js.map +1 -1
  19. package/dist/meeting/request.js +25 -0
  20. package/dist/meeting/request.js.map +1 -1
  21. package/dist/meeting/util.js +30 -11
  22. package/dist/meeting/util.js.map +1 -1
  23. package/dist/meeting-info/meeting-info-v2.js +29 -21
  24. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  25. package/dist/meetings/index.js +31 -25
  26. package/dist/meetings/index.js.map +1 -1
  27. package/dist/member/types.js.map +1 -1
  28. package/dist/members/collection.js +13 -0
  29. package/dist/members/collection.js.map +1 -1
  30. package/dist/members/index.js +42 -20
  31. package/dist/members/index.js.map +1 -1
  32. package/dist/members/util.js +7 -2
  33. package/dist/members/util.js.map +1 -1
  34. package/dist/metrics/constants.js +2 -1
  35. package/dist/metrics/constants.js.map +1 -1
  36. package/dist/reachability/index.js +3 -3
  37. package/dist/reachability/index.js.map +1 -1
  38. package/dist/types/constants.d.ts +2 -0
  39. package/dist/types/locus-info/index.d.ts +54 -1
  40. package/dist/types/media/properties.d.ts +21 -0
  41. package/dist/types/meeting/in-meeting-actions.d.ts +2 -0
  42. package/dist/types/meeting/index.d.ts +11 -1
  43. package/dist/types/meeting/request.d.ts +9 -0
  44. package/dist/types/meeting/util.d.ts +10 -3
  45. package/dist/types/meeting-info/meeting-info-v2.d.ts +6 -3
  46. package/dist/types/meetings/index.d.ts +3 -1
  47. package/dist/types/member/types.d.ts +1 -0
  48. package/dist/types/members/collection.d.ts +6 -0
  49. package/dist/types/members/index.d.ts +12 -2
  50. package/dist/types/members/util.d.ts +6 -3
  51. package/dist/types/metrics/constants.d.ts +1 -0
  52. package/dist/webinar/index.js +1 -1
  53. package/package.json +17 -17
  54. package/src/constants.ts +2 -0
  55. package/src/locus-info/index.ts +84 -9
  56. package/src/locus-info/parser.ts +5 -1
  57. package/src/media/properties.ts +43 -0
  58. package/src/meeting/in-meeting-actions.ts +4 -0
  59. package/src/meeting/index.ts +91 -4
  60. package/src/meeting/muteState.ts +2 -6
  61. package/src/meeting/request.ts +23 -0
  62. package/src/meeting/util.ts +41 -20
  63. package/src/meeting-info/meeting-info-v2.ts +24 -5
  64. package/src/meetings/index.ts +9 -3
  65. package/src/member/types.ts +1 -0
  66. package/src/members/collection.ts +11 -0
  67. package/src/members/index.ts +38 -5
  68. package/src/members/util.ts +18 -2
  69. package/src/metrics/constants.ts +1 -0
  70. package/src/reachability/index.ts +3 -3
  71. package/test/unit/spec/common/browser-detection.js +0 -24
  72. package/test/unit/spec/locus-info/index.js +30 -15
  73. package/test/unit/spec/locus-info/parser.js +3 -2
  74. package/test/unit/spec/media/properties.ts +137 -0
  75. package/test/unit/spec/meeting/in-meeting-actions.ts +2 -0
  76. package/test/unit/spec/meeting/index.js +255 -27
  77. package/test/unit/spec/meeting/muteState.js +32 -6
  78. package/test/unit/spec/meeting/request.js +21 -0
  79. package/test/unit/spec/meeting/utils.js +45 -16
  80. package/test/unit/spec/meeting-info/meetinginfov2.js +8 -3
  81. package/test/unit/spec/meetings/index.js +10 -5
  82. package/test/unit/spec/members/collection.js +120 -0
  83. package/test/unit/spec/members/index.js +72 -3
  84. package/test/unit/spec/members/request.js +55 -0
  85. package/test/unit/spec/members/utils.js +116 -14
  86. package/test/unit/spec/reachability/index.ts +158 -3
  87. package/test/unit/spec/roap/turnDiscovery.ts +3 -3
@@ -12,7 +12,7 @@ describe('plugin-meetings', () => {
12
12
  let video;
13
13
  let originalRemoteUpdateAudioVideo;
14
14
 
15
- const fakeLocus = {info: 'this is a fake locus'};
15
+ const fakeLocusResponse = {body: {locus: {info: 'this is a fake locus'}}};
16
16
 
17
17
  const createFakeLocalStream = (id, userMuted, systemMuted) => {
18
18
  return {
@@ -38,9 +38,6 @@ describe('plugin-meetings', () => {
38
38
  unmuteAllowed: true,
39
39
  remoteVideoMuted: false,
40
40
  unmuteVideoAllowed: true,
41
- locusInfo: {
42
- handleLocusDelta: sinon.stub(),
43
- },
44
41
  members: {
45
42
  selfId: 'fake self id',
46
43
  muteMember: sinon.stub().resolves(),
@@ -49,7 +46,8 @@ describe('plugin-meetings', () => {
49
46
 
50
47
  originalRemoteUpdateAudioVideo = MeetingUtil.remoteUpdateAudioVideo;
51
48
 
52
- MeetingUtil.remoteUpdateAudioVideo = sinon.stub().resolves(fakeLocus);
49
+ MeetingUtil.remoteUpdateAudioVideo = sinon.stub().resolves(fakeLocusResponse);
50
+ MeetingUtil.updateLocusFromApiResponse = sinon.stub();
53
51
 
54
52
  audio = createMuteState(AUDIO, meeting, true);
55
53
  video = createMuteState(VIDEO, meeting, true);
@@ -141,6 +139,7 @@ describe('plugin-meetings', () => {
141
139
  // and local unmute was sent to server
142
140
  assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
143
141
  assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, false, undefined);
142
+ assert.calledWith(MeetingUtil.updateLocusFromApiResponse, meeting, fakeLocusResponse);
144
143
 
145
144
  assert.isFalse(audio.isMuted());
146
145
  });
@@ -173,6 +172,7 @@ describe('plugin-meetings', () => {
173
172
 
174
173
  // system was muted so local unmute was not sent to server
175
174
  assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
175
+ assert.notCalled(MeetingUtil.updateLocusFromApiResponse);
176
176
 
177
177
  assert.isTrue(audio.isMuted());
178
178
  });
@@ -207,6 +207,7 @@ describe('plugin-meetings', () => {
207
207
  // and local unmute was sent to server
208
208
  assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
209
209
  assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, false);
210
+ assert.calledWith(MeetingUtil.updateLocusFromApiResponse, meeting, fakeLocusResponse);
210
211
 
211
212
  assert.isFalse(video.isMuted());
212
213
  });
@@ -219,7 +220,9 @@ describe('plugin-meetings', () => {
219
220
 
220
221
  assert.isTrue(video.isMuted());
221
222
 
223
+ await testUtils.flushPromises();
222
224
  MeetingUtil.remoteUpdateAudioVideo.resetHistory();
225
+ MeetingUtil.updateLocusFromApiResponse.resetHistory();
223
226
 
224
227
  // now simulate server requiring us to locally unmute
225
228
  // assuming setServerMuted succeeds at updating userMuted
@@ -239,6 +242,7 @@ describe('plugin-meetings', () => {
239
242
 
240
243
  // system was muted so local unmute was not sent to server
241
244
  assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
245
+ assert.notCalled(MeetingUtil.updateLocusFromApiResponse);
242
246
 
243
247
  assert.isTrue(video.isMuted());
244
248
  });
@@ -443,6 +447,7 @@ describe('plugin-meetings', () => {
443
447
 
444
448
  assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
445
449
  assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, true, undefined);
450
+ assert.calledWith(MeetingUtil.updateLocusFromApiResponse, meeting, fakeLocusResponse);
446
451
 
447
452
  // now allow the first request to complete
448
453
  serverResponseResolve();
@@ -559,6 +564,7 @@ describe('plugin-meetings', () => {
559
564
  await testUtils.flushPromises();
560
565
 
561
566
  MeetingUtil.remoteUpdateAudioVideo.resetHistory();
567
+ MeetingUtil.updateLocusFromApiResponse.resetHistory();
562
568
  };
563
569
 
564
570
  const setupSpies = (mediaType) => {
@@ -605,13 +611,15 @@ describe('plugin-meetings', () => {
605
611
  {mediaType: VIDEO, title: 'video'},
606
612
  ];
607
613
 
614
+ const fakeLocusResponse = {body: {locus: {info: 'fake locus'}}};
615
+
608
616
  tests.forEach(({mediaType, title}) =>
609
617
  describe(title, () => {
610
618
  let originalRemoteUpdateAudioVideo;
611
619
 
612
620
  beforeEach(() => {
613
621
  originalRemoteUpdateAudioVideo = MeetingUtil.remoteUpdateAudioVideo;
614
- MeetingUtil.remoteUpdateAudioVideo = sinon.stub().resolves({info: 'fake locus'});
622
+ MeetingUtil.remoteUpdateAudioVideo = sinon.stub().resolves(fakeLocusResponse);
615
623
  });
616
624
 
617
625
  afterEach(() => {
@@ -660,6 +668,7 @@ describe('plugin-meetings', () => {
660
668
  assert.calledWith(setUnmuteAllowedSpy, muteState.state.server.unmuteAllowed);
661
669
  assert.notCalled(setServerMutedSpy);
662
670
  assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
671
+ assert.notCalled(MeetingUtil.updateLocusFromApiResponse);
663
672
  assert.isTrue(muteState.state.client.localMute);
664
673
  });
665
674
 
@@ -672,6 +681,7 @@ describe('plugin-meetings', () => {
672
681
  assert.calledWith(setUnmuteAllowedSpy, muteState.state.server.unmuteAllowed);
673
682
  assert.notCalled(setServerMutedSpy);
674
683
  assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
684
+ assert.notCalled(MeetingUtil.updateLocusFromApiResponse);
675
685
  assert.isTrue(muteState.state.client.localMute);
676
686
  });
677
687
 
@@ -681,9 +691,12 @@ describe('plugin-meetings', () => {
681
691
 
682
692
  muteState.init(meeting);
683
693
 
694
+ await testUtils.flushPromises();
695
+
684
696
  assert.calledWith(setUnmuteAllowedSpy, muteState.state.server.unmuteAllowed);
685
697
  assert.notCalled(setServerMutedSpy);
686
698
  assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
699
+ assert.calledOnceWithExactly(MeetingUtil.updateLocusFromApiResponse, meeting, fakeLocusResponse);
687
700
  assert.isFalse(muteState.state.client.localMute);
688
701
  });
689
702
 
@@ -707,6 +720,7 @@ describe('plugin-meetings', () => {
707
720
  simulateUserMute(mediaType, true);
708
721
  muteState.handleLocalStreamMuteStateChange(meeting);
709
722
  assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
723
+ assert.notCalled(MeetingUtil.updateLocusFromApiResponse);
710
724
 
711
725
  assert.isFalse(muteState.state.client.localMute);
712
726
  });
@@ -716,8 +730,11 @@ describe('plugin-meetings', () => {
716
730
 
717
731
  simulateUserMute(mediaType, false);
718
732
  muteState.handleLocalStreamMuteStateChange(meeting);
733
+ await testUtils.flushPromises();
734
+
719
735
  assert.equal(muteState.state.client.localMute, false);
720
736
  assert.called(MeetingUtil.remoteUpdateAudioVideo);
737
+ assert.calledOnceWithExactly(MeetingUtil.updateLocusFromApiResponse, meeting, fakeLocusResponse);
721
738
  });
722
739
 
723
740
  it('tests localMute - user mute from false to true', async () => {
@@ -725,8 +742,11 @@ describe('plugin-meetings', () => {
725
742
 
726
743
  simulateUserMute(mediaType, true);
727
744
  muteState.handleLocalStreamMuteStateChange(meeting);
745
+ await testUtils.flushPromises();
746
+
728
747
  assert.equal(muteState.state.client.localMute, true);
729
748
  assert.called(MeetingUtil.remoteUpdateAudioVideo);
749
+ assert.calledOnceWithExactly(MeetingUtil.updateLocusFromApiResponse, meeting, fakeLocusResponse);
730
750
  });
731
751
 
732
752
  it('tests localMute - system mute from true to false', async () => {
@@ -734,8 +754,11 @@ describe('plugin-meetings', () => {
734
754
 
735
755
  simulateSystemMute(mediaType, false);
736
756
  muteState.handleLocalStreamMuteStateChange(meeting);
757
+ await testUtils.flushPromises();
758
+
737
759
  assert.equal(muteState.state.client.localMute, false);
738
760
  assert.called(MeetingUtil.remoteUpdateAudioVideo);
761
+ assert.calledOnceWithExactly(MeetingUtil.updateLocusFromApiResponse, meeting, fakeLocusResponse);
739
762
  });
740
763
 
741
764
  it('tests localMute - system mute from false to true', async () => {
@@ -743,8 +766,11 @@ describe('plugin-meetings', () => {
743
766
 
744
767
  simulateSystemMute(mediaType, true);
745
768
  muteState.handleLocalStreamMuteStateChange(meeting);
769
+ await testUtils.flushPromises();
770
+
746
771
  assert.equal(muteState.state.client.localMute, true);
747
772
  assert.called(MeetingUtil.remoteUpdateAudioVideo);
773
+ assert.calledOnceWithExactly(MeetingUtil.updateLocusFromApiResponse, meeting, fakeLocusResponse);
748
774
  });
749
775
  });
750
776
 
@@ -897,4 +897,25 @@ describe('plugin-meetings', () => {
897
897
  });
898
898
  });
899
899
  });
900
+
901
+ describe('#notifyHost', () => {
902
+ it('check locus status', async () => {
903
+ const siteFullUrl = 'ats062222cvg.webex.com';
904
+ const locusId = 'locusId';
905
+ const meetingUuid = 'meetingUuid';
906
+ const displayName = ['user1', 'user2'];
907
+ await meetingsRequest.notifyHost(siteFullUrl, locusId, meetingUuid, displayName);
908
+ assert.deepEqual(meetingsRequest.request.getCall(0).args[0], {
909
+ method: 'POST',
910
+ uri: `https://${siteFullUrl}/wbxappapi/v1/meetings/${meetingUuid}/notifyhost`,
911
+ body: {
912
+ displayName,
913
+ size: displayName?.length,
914
+ },
915
+ headers: {
916
+ locusId,
917
+ }
918
+ });
919
+ });
920
+ });
900
921
  });
@@ -228,11 +228,11 @@ describe('plugin-meetings', () => {
228
228
  });
229
229
  });
230
230
 
231
- describe('updateLocusWithDelta', () => {
232
- it('should call handleLocusDelta with the new delta locus', () => {
231
+ describe('updateLocusFromApiResponse', () => {
232
+ it('should call handleLocusAPIResponse with the response body', () => {
233
233
  const meeting = {
234
234
  locusInfo: {
235
- handleLocusDelta: sinon.stub(),
235
+ handleLocusAPIResponse: sinon.stub(),
236
236
  },
237
237
  };
238
238
 
@@ -242,16 +242,16 @@ describe('plugin-meetings', () => {
242
242
  },
243
243
  };
244
244
 
245
- const response = MeetingUtil.updateLocusWithDelta(meeting, originalResponse);
245
+ const response = MeetingUtil.updateLocusFromApiResponse(meeting, originalResponse);
246
246
 
247
247
  assert.deepEqual(response, originalResponse);
248
- assert.calledOnceWithExactly(meeting.locusInfo.handleLocusDelta, 'locus', meeting);
248
+ assert.calledOnceWithExactly(meeting.locusInfo.handleLocusAPIResponse, meeting, originalResponse.body);
249
249
  });
250
250
 
251
251
  it('should handle locus being missing from the response', () => {
252
252
  const meeting = {
253
253
  locusInfo: {
254
- handleLocusDelta: sinon.stub(),
254
+ handleLocusAPIResponse: sinon.stub(),
255
255
  },
256
256
  };
257
257
 
@@ -259,10 +259,10 @@ describe('plugin-meetings', () => {
259
259
  body: {},
260
260
  };
261
261
 
262
- const response = MeetingUtil.updateLocusWithDelta(meeting, originalResponse);
262
+ const response = MeetingUtil.updateLocusFromApiResponse(meeting, originalResponse);
263
263
 
264
264
  assert.deepEqual(response, originalResponse);
265
- assert.notCalled(meeting.locusInfo.handleLocusDelta);
265
+ assert.notCalled(meeting.locusInfo.handleLocusAPIResponse);
266
266
  });
267
267
 
268
268
  it('should work with an undefined meeting', () => {
@@ -272,14 +272,14 @@ describe('plugin-meetings', () => {
272
272
  },
273
273
  };
274
274
 
275
- const response = MeetingUtil.updateLocusWithDelta(undefined, originalResponse);
275
+ const response = MeetingUtil.updateLocusFromApiResponse(undefined, originalResponse);
276
276
  assert.deepEqual(response, originalResponse);
277
277
  });
278
278
  });
279
279
 
280
280
  describe('generateLocusDeltaRequest', () => {
281
281
  it('generates the correct wrapper function', async () => {
282
- const updateLocusWithDeltaSpy = sinon.spy(MeetingUtil, 'updateLocusWithDelta');
282
+ const updateLocusFromApiResponseSpy = sinon.spy(MeetingUtil, 'updateLocusFromApiResponse');
283
283
  const addSequenceSpy = sinon.spy(MeetingUtil, 'addSequence');
284
284
 
285
285
  const meeting = {
@@ -296,16 +296,16 @@ describe('plugin-meetings', () => {
296
296
  let result = await locusDeltaRequest(options);
297
297
 
298
298
  assert.equal(result, 'result');
299
- assert.calledOnceWithExactly(updateLocusWithDeltaSpy, meeting, 'result');
299
+ assert.calledOnceWithExactly(updateLocusFromApiResponseSpy, meeting, 'result');
300
300
  assert.calledOnceWithExactly(addSequenceSpy, meeting, options.body);
301
301
 
302
- updateLocusWithDeltaSpy.resetHistory();
302
+ updateLocusFromApiResponseSpy.resetHistory();
303
303
  addSequenceSpy.resetHistory();
304
304
 
305
305
  // body missing from options
306
306
  result = await locusDeltaRequest({});
307
307
  assert.equal(result, 'result');
308
- assert.calledOnceWithExactly(updateLocusWithDeltaSpy, meeting, 'result');
308
+ assert.calledOnceWithExactly(updateLocusFromApiResponseSpy, meeting, 'result');
309
309
  assert.calledOnceWithExactly(addSequenceSpy, meeting, options.body);
310
310
 
311
311
  // meeting disappears so the WeakRef returns undefined
@@ -359,7 +359,11 @@ describe('plugin-meetings', () => {
359
359
  });
360
360
 
361
361
  describe('remoteUpdateAudioVideo', () => {
362
- it('#Should call meetingRequest.locusMediaRequest with correct parameters', async () => {
362
+ it('#Should call meetingRequest.locusMediaRequest with correct parameters and return the full response', async () => {
363
+ const fakeResponse = {
364
+ body: { locus: { url: 'locusUrl'}},
365
+ headers: { },
366
+ };
363
367
  const meeting = {
364
368
  id: 'meeting-id',
365
369
  mediaId: '12345',
@@ -368,13 +372,14 @@ describe('plugin-meetings', () => {
368
372
  sequence: {},
369
373
  },
370
374
  locusMediaRequest: {
371
- send: sinon.stub().resolves({body: {}, headers: {}}),
375
+ send: sinon.stub().resolves(fakeResponse),
372
376
  },
373
377
  getWebexObject: sinon.stub().returns(webex),
374
378
  };
375
379
 
376
- await MeetingUtil.remoteUpdateAudioVideo(meeting, true, false);
380
+ const result = await MeetingUtil.remoteUpdateAudioVideo(meeting, true, false);
377
381
 
382
+ assert.deepEqual(result, fakeResponse);
378
383
  assert.calledOnceWithExactly(meeting.locusMediaRequest.send, {
379
384
  mediaId: '12345',
380
385
  muteOptions: {
@@ -972,6 +977,9 @@ describe('plugin-meetings', () => {
972
977
  {functionName: 'isLocalRecordingPaused', displayHint: 'LOCAL_RECORDING_STATUS_PAUSED'},
973
978
 
974
979
  {functionName: 'isManualCaptionActive', displayHint: 'MANUAL_CAPTION_STATUS_ACTIVE'},
980
+
981
+ {functionName: 'isSpokenLanguageAutoDetectionEnabled', displayHint: 'SPOKEN_LANGUAGE_AUTO_DETECTION_ENABLED'},
982
+
975
983
  {functionName: 'isWebexAssistantActive', displayHint: 'WEBEX_ASSISTANT_STATUS_ACTIVE'},
976
984
  {functionName: 'canViewCaptionPanel', displayHint: 'ENABLE_CAPTION_PANEL'},
977
985
  {functionName: 'isRealTimeTranslationEnabled', displayHint: 'DISPLAY_REAL_TIME_TRANSLATION'},
@@ -1310,6 +1318,27 @@ describe('plugin-meetings', () => {
1310
1318
  });
1311
1319
  });
1312
1320
 
1321
+ describe('getCaEventLabelsForIpVersion', () => {
1322
+ [
1323
+ {ipver: IP_VERSION.unknown, expectedLabels: undefined},
1324
+ {ipver: IP_VERSION.only_ipv4, expectedLabels: ['hasIpv4_true']},
1325
+ {ipver: IP_VERSION.only_ipv6, expectedLabels: ['hasIpv6_true']},
1326
+ {
1327
+ ipver: IP_VERSION.ipv4_and_ipv6,
1328
+ expectedLabels: ['hasIpv4_true', 'hasIpv6_true'],
1329
+ },
1330
+ ].forEach(({ipver, expectedLabels}) => {
1331
+ it(`returns expected labels when ipver=${ipver}`, () => {
1332
+ sinon.stub(MeetingUtil, 'getIpVersion').returns(ipver);
1333
+
1334
+ const result = MeetingUtil.getCaEventLabelsForIpVersion(webex);
1335
+
1336
+ assert.calledOnceWithExactly(MeetingUtil.getIpVersion, webex);
1337
+ assert.deepEqual(result, expectedLabels);
1338
+ });
1339
+ });
1340
+ });
1341
+
1313
1342
  describe('getChangeMeetingFloorErrorPayload', () => {
1314
1343
  [
1315
1344
  {
@@ -218,6 +218,7 @@ describe('plugin-meetings', () => {
218
218
  invitees: invitee,
219
219
  installedOrgID: undefined,
220
220
  schedule: true,
221
+ classificationId: undefined,
221
222
  },
222
223
  });
223
224
 
@@ -652,7 +653,8 @@ describe('plugin-meetings', () => {
652
653
  assert.calledOnceWithExactly(
653
654
  meetingInfo.createAdhocSpaceMeeting,
654
655
  'conversationUrl',
655
- installedOrgID
656
+ installedOrgID,
657
+ null,
656
658
  );
657
659
  assert.notCalled(webex.request);
658
660
  meetingInfo.createAdhocSpaceMeeting.restore();
@@ -1148,6 +1150,7 @@ describe('plugin-meetings', () => {
1148
1150
  describe('createAdhocSpaceMeeting', () => {
1149
1151
  const conversationUrl = 'https://conversationUrl/xxx';
1150
1152
  const installedOrgID = '12345';
1153
+ const classificationId = '123456';
1151
1154
 
1152
1155
  const setup = () => {
1153
1156
  const invitee = [];
@@ -1173,7 +1176,7 @@ describe('plugin-meetings', () => {
1173
1176
  body: conversation,
1174
1177
  });
1175
1178
 
1176
- const result = await meetingInfo.createAdhocSpaceMeeting(conversationUrl, installedOrgID);
1179
+ const result = await meetingInfo.createAdhocSpaceMeeting(conversationUrl, installedOrgID, classificationId);
1177
1180
 
1178
1181
  assert.calledWith(webex.request, {
1179
1182
  uri: conversationUrl,
@@ -1192,6 +1195,7 @@ describe('plugin-meetings', () => {
1192
1195
  invitees: invitee,
1193
1196
  installedOrgID: installedOrgID,
1194
1197
  schedule: false,
1198
+ classificationId,
1195
1199
  },
1196
1200
  });
1197
1201
  assert.calledOnce(Metrics.sendBehavioralMetric);
@@ -1206,7 +1210,7 @@ describe('plugin-meetings', () => {
1206
1210
  webex.request = sinon.stub().resolves({
1207
1211
  body: conversation,
1208
1212
  });
1209
- await meetingInfo.createAdhocSpaceMeeting(conversationUrl, installedOrgID);
1213
+ await meetingInfo.createAdhocSpaceMeeting(conversationUrl, installedOrgID, classificationId);
1210
1214
 
1211
1215
  assert.calledWith(webex.request, {
1212
1216
  uri: conversationUrl,
@@ -1224,6 +1228,7 @@ describe('plugin-meetings', () => {
1224
1228
  invitees: invitee,
1225
1229
  installedOrgID,
1226
1230
  schedule: false,
1231
+ classificationId,
1227
1232
  },
1228
1233
  });
1229
1234
  assert(Metrics.sendBehavioralMetric.calledOnce);
@@ -3,10 +3,6 @@
3
3
  */
4
4
  import 'jsdom-global/register';
5
5
 
6
- // Polyfill for crypto: https://github.com/jsdom/jsdom/issues/1612#issuecomment-663210638
7
- import {Crypto} from '@peculiar/webcrypto';
8
- global.crypto = new Crypto();
9
-
10
6
  import Device from '@webex/internal-plugin-device';
11
7
  import {CatalogDetails} from '@webex/internal-plugin-device';
12
8
  import Mercury from '@webex/internal-plugin-mercury';
@@ -1099,6 +1095,7 @@ describe('plugin-meetings', () => {
1099
1095
  const FAKE_USE_RANDOM_DELAY = true;
1100
1096
  const correlationId = 'my-correlationId';
1101
1097
  const sessionCorrelationId = 'my-session-correlationId';
1098
+ const classificationId = 'my-classificationId';
1102
1099
  const callStateForMetrics = {
1103
1100
  sessionCorrelationId: 'my-session-correlationId2',
1104
1101
  correlationId: 'my-correlationId2',
@@ -1119,7 +1116,8 @@ describe('plugin-meetings', () => {
1119
1116
  callStateForMetrics,
1120
1117
  undefined,
1121
1118
  undefined,
1122
- sessionCorrelationId
1119
+ sessionCorrelationId,
1120
+ classificationId
1123
1121
  );
1124
1122
  assert.calledOnceWithExactly(fakeMeeting.updateCallStateForMetrics, {
1125
1123
  ...callStateForMetrics,
@@ -1201,6 +1199,13 @@ describe('plugin-meetings', () => {
1201
1199
  );
1202
1200
  });
1203
1201
 
1202
+ it('calls createMeeting with classificationId and returns its promise', async () => {
1203
+ await checkCallCreateMeeting(
1204
+ [test1, test2, FAKE_USE_RANDOM_DELAY, {}, undefined, true, callStateForMetrics, undefined, undefined, undefined, classificationId],
1205
+ [test1, test2, FAKE_USE_RANDOM_DELAY, {}, callStateForMetrics, true, undefined, undefined, classificationId],
1206
+ );
1207
+ });
1208
+
1204
1209
  it('calls createMeeting with callStateForMetrics overwritten with correlationId and returns its promise', async () => {
1205
1210
  await checkCallCreateMeeting(
1206
1211
  [test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true, callStateForMetrics],
@@ -0,0 +1,120 @@
1
+ const { default: MembersCollection } = require("../../../../src/members/collection");
2
+ const { default: Member } = require("../../../../src/member");
3
+ const { assert } = require('@webex/test-helper-chai');
4
+
5
+
6
+ describe('plugin-meetings', () => {
7
+ describe('MembersCollection', () => {
8
+ let collection;
9
+ let member1;
10
+ let member2;
11
+ const participant1 = { controls: {}, status: {} };
12
+ const participant2 = { controls: {}, status: {} };
13
+
14
+ beforeEach(() => {
15
+ collection = new MembersCollection();
16
+ member1 = new Member(participant1);
17
+ member2 = new Member(participant2);
18
+ });
19
+
20
+ it('starts with no members', () => {
21
+ assert.equal(Object.keys(collection.getAll()).length, 0);
22
+ });
23
+
24
+ it('can add members', () => {
25
+ collection.set('member1', member1);
26
+ assert.equal(Object.keys(collection.getAll()).length, 1);
27
+ assert.equal(collection.get('member1'), member1);
28
+
29
+ collection.set('member2', member2);
30
+ assert.equal(Object.keys(collection.getAll()).length, 2);
31
+ assert.equal(collection.get('member2'), member2);
32
+ });
33
+
34
+ it('can remove members', () => {
35
+ // Add some members first
36
+ collection.set('member1', member1);
37
+ collection.set('member2', member2);
38
+ assert.equal(Object.keys(collection.getAll()).length, 2);
39
+
40
+ // Remove one member
41
+ collection.remove('member1');
42
+ assert.equal(Object.keys(collection.getAll()).length, 1);
43
+ assert.equal(collection.get('member1'), undefined);
44
+ assert.equal(collection.get('member2'), member2);
45
+
46
+ // Remove another member
47
+ collection.remove('member2');
48
+ assert.equal(Object.keys(collection.getAll()).length, 0);
49
+ assert.equal(collection.get('member2'), undefined);
50
+
51
+ // Removing non-existent member should not cause errors
52
+ collection.remove('nonExistent');
53
+ assert.equal(Object.keys(collection.getAll()).length, 0);
54
+ });
55
+
56
+ describe('reset', () => {
57
+ it('removes all members', () => {
58
+ // Add some members first
59
+ collection.set('member1', member1);
60
+ collection.set('member2', member2);
61
+ assert.equal(Object.keys(collection.getAll()).length, 2);
62
+
63
+ // Reset should clear all members
64
+ collection.reset();
65
+ assert.equal(Object.keys(collection.getAll()).length, 0);
66
+ assert.equal(collection.get('member1'), undefined);
67
+ assert.equal(collection.get('member2'), undefined);
68
+ });
69
+ });
70
+
71
+ describe('setAll', () => {
72
+ it('replaces all members with new collection', () => {
73
+ // Add initial member
74
+ collection.set('member1', member1);
75
+ assert.equal(Object.keys(collection.getAll()).length, 1);
76
+
77
+ // Set all with new collection
78
+ const newMembers = {
79
+ 'member2': member2,
80
+ 'member3': new Member(participant1)
81
+ };
82
+ collection.setAll(newMembers);
83
+
84
+ assert.equal(Object.keys(collection.getAll()).length, 2);
85
+ assert.equal(collection.get('member1'), undefined);
86
+ assert.equal(collection.get('member2'), member2);
87
+ assert.exists(collection.get('member3'));
88
+ });
89
+ });
90
+
91
+ describe('get', () => {
92
+ it('returns undefined for non-existent members', () => {
93
+ assert.equal(collection.get('nonExistent'), undefined);
94
+ });
95
+
96
+ it('returns correct member for existing id', () => {
97
+ collection.set('member1', member1);
98
+ assert.equal(collection.get('member1'), member1);
99
+ });
100
+ });
101
+
102
+ describe('getAll', () => {
103
+ it('returns empty object when no members', () => {
104
+ const allMembers = collection.getAll();
105
+ assert.isObject(allMembers);
106
+ assert.equal(Object.keys(allMembers).length, 0);
107
+ });
108
+
109
+ it('returns all members', () => {
110
+ collection.set('member1', member1);
111
+ collection.set('member2', member2);
112
+
113
+ const allMembers = collection.getAll();
114
+ assert.equal(Object.keys(allMembers).length, 2);
115
+ assert.equal(allMembers.member1, member1);
116
+ assert.equal(allMembers.member2, member2);
117
+ });
118
+ });
119
+ });
120
+ });