@webex/plugin-meetings 3.12.0-next.8 → 3.12.0-task-refactor.1

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 (201) hide show
  1. package/dist/annotation/index.js +5 -14
  2. package/dist/annotation/index.js.map +1 -1
  3. package/dist/breakouts/breakout.js +1 -1
  4. package/dist/breakouts/index.js +1 -1
  5. package/dist/config.js +2 -8
  6. package/dist/config.js.map +1 -1
  7. package/dist/constants.js +6 -29
  8. package/dist/constants.js.map +1 -1
  9. package/dist/hashTree/hashTreeParser.js +29 -1563
  10. package/dist/hashTree/hashTreeParser.js.map +1 -1
  11. package/dist/hashTree/types.js +3 -13
  12. package/dist/hashTree/types.js.map +1 -1
  13. package/dist/index.js +2 -11
  14. package/dist/index.js.map +1 -1
  15. package/dist/interceptors/index.js +0 -7
  16. package/dist/interceptors/index.js.map +1 -1
  17. package/dist/interceptors/locusRouteToken.js +5 -27
  18. package/dist/interceptors/locusRouteToken.js.map +1 -1
  19. package/dist/interpretation/index.js +2 -2
  20. package/dist/interpretation/index.js.map +1 -1
  21. package/dist/interpretation/siLanguage.js +1 -1
  22. package/dist/locus-info/controlsUtils.js +3 -7
  23. package/dist/locus-info/controlsUtils.js.map +1 -1
  24. package/dist/locus-info/index.js +247 -642
  25. package/dist/locus-info/index.js.map +1 -1
  26. package/dist/locus-info/selfUtils.js +0 -1
  27. package/dist/locus-info/selfUtils.js.map +1 -1
  28. package/dist/locus-info/types.js.map +1 -1
  29. package/dist/media/MediaConnectionAwaiter.js +1 -57
  30. package/dist/media/MediaConnectionAwaiter.js.map +1 -1
  31. package/dist/media/properties.js +2 -4
  32. package/dist/media/properties.js.map +1 -1
  33. package/dist/meeting/in-meeting-actions.js +1 -7
  34. package/dist/meeting/in-meeting-actions.js.map +1 -1
  35. package/dist/meeting/index.js +1036 -1481
  36. package/dist/meeting/index.js.map +1 -1
  37. package/dist/meeting/request.js +0 -50
  38. package/dist/meeting/request.js.map +1 -1
  39. package/dist/meeting/request.type.js.map +1 -1
  40. package/dist/meeting/util.js +3 -133
  41. package/dist/meeting/util.js.map +1 -1
  42. package/dist/meetings/index.js +59 -142
  43. package/dist/meetings/index.js.map +1 -1
  44. package/dist/meetings/util.js +7 -11
  45. package/dist/meetings/util.js.map +1 -1
  46. package/dist/member/index.js +0 -10
  47. package/dist/member/index.js.map +1 -1
  48. package/dist/member/util.js +0 -10
  49. package/dist/member/util.js.map +1 -1
  50. package/dist/metrics/constants.js +1 -7
  51. package/dist/metrics/constants.js.map +1 -1
  52. package/dist/multistream/mediaRequestManager.js +60 -9
  53. package/dist/multistream/mediaRequestManager.js.map +1 -1
  54. package/dist/multistream/remoteMediaManager.js +0 -11
  55. package/dist/multistream/remoteMediaManager.js.map +1 -1
  56. package/dist/multistream/sendSlotManager.js +2 -116
  57. package/dist/multistream/sendSlotManager.js.map +1 -1
  58. package/dist/reachability/clusterReachability.js +18 -171
  59. package/dist/reachability/clusterReachability.js.map +1 -1
  60. package/dist/reachability/index.js +11 -21
  61. package/dist/reachability/index.js.map +1 -1
  62. package/dist/reachability/reachabilityPeerConnection.js +1 -1
  63. package/dist/reachability/reachabilityPeerConnection.js.map +1 -1
  64. package/dist/reactions/reactions.type.js.map +1 -1
  65. package/dist/reconnection-manager/index.js +1 -0
  66. package/dist/reconnection-manager/index.js.map +1 -1
  67. package/dist/types/common/browser-detection.d.ts +0 -1
  68. package/dist/types/common/events/events-scope.d.ts +0 -1
  69. package/dist/types/common/events/events.d.ts +0 -1
  70. package/dist/types/config.d.ts +0 -5
  71. package/dist/types/constants.d.ts +1 -24
  72. package/dist/types/hashTree/hashTreeParser.d.ts +11 -260
  73. package/dist/types/hashTree/types.d.ts +0 -20
  74. package/dist/types/index.d.ts +0 -1
  75. package/dist/types/interceptors/index.d.ts +1 -2
  76. package/dist/types/interceptors/locusRouteToken.d.ts +0 -2
  77. package/dist/types/locus-info/index.d.ts +47 -68
  78. package/dist/types/locus-info/types.d.ts +12 -28
  79. package/dist/types/media/MediaConnectionAwaiter.d.ts +1 -10
  80. package/dist/types/media/properties.d.ts +1 -2
  81. package/dist/types/meeting/in-meeting-actions.d.ts +0 -6
  82. package/dist/types/meeting/index.d.ts +7 -86
  83. package/dist/types/meeting/request.d.ts +1 -16
  84. package/dist/types/meeting/request.type.d.ts +0 -5
  85. package/dist/types/meeting/util.d.ts +0 -31
  86. package/dist/types/meeting-info/util.d.ts +0 -1
  87. package/dist/types/meeting-info/utilv2.d.ts +0 -1
  88. package/dist/types/meetings/index.d.ts +2 -4
  89. package/dist/types/member/index.d.ts +0 -1
  90. package/dist/types/member/types.d.ts +4 -4
  91. package/dist/types/member/util.d.ts +0 -5
  92. package/dist/types/metrics/constants.d.ts +0 -6
  93. package/dist/types/multistream/mediaRequestManager.d.ts +23 -0
  94. package/dist/types/multistream/sendSlotManager.d.ts +1 -23
  95. package/dist/types/reachability/clusterReachability.d.ts +3 -30
  96. package/dist/types/reactions/reactions.type.d.ts +0 -1
  97. package/dist/types/recording-controller/util.d.ts +5 -5
  98. package/dist/types/roap/index.d.ts +1 -1
  99. package/dist/webinar/index.js +163 -438
  100. package/dist/webinar/index.js.map +1 -1
  101. package/package.json +24 -26
  102. package/src/annotation/index.ts +7 -27
  103. package/src/config.ts +0 -5
  104. package/src/constants.ts +1 -30
  105. package/src/hashTree/hashTreeParser.ts +25 -1523
  106. package/src/hashTree/types.ts +1 -24
  107. package/src/index.ts +1 -8
  108. package/src/interceptors/index.ts +1 -2
  109. package/src/interceptors/locusRouteToken.ts +5 -22
  110. package/src/interpretation/index.ts +2 -2
  111. package/src/locus-info/controlsUtils.ts +0 -17
  112. package/src/locus-info/index.ts +213 -707
  113. package/src/locus-info/selfUtils.ts +0 -1
  114. package/src/locus-info/types.ts +12 -27
  115. package/src/media/MediaConnectionAwaiter.ts +1 -41
  116. package/src/media/properties.ts +1 -3
  117. package/src/meeting/in-meeting-actions.ts +0 -12
  118. package/src/meeting/index.ts +84 -461
  119. package/src/meeting/request.ts +0 -42
  120. package/src/meeting/request.type.ts +0 -6
  121. package/src/meeting/util.ts +2 -160
  122. package/src/meetings/index.ts +60 -180
  123. package/src/meetings/util.ts +9 -10
  124. package/src/member/index.ts +0 -10
  125. package/src/member/util.ts +0 -12
  126. package/src/metrics/constants.ts +0 -7
  127. package/src/multistream/mediaRequestManager.ts +54 -4
  128. package/src/multistream/remoteMediaManager.ts +0 -13
  129. package/src/multistream/sendSlotManager.ts +3 -97
  130. package/src/reachability/clusterReachability.ts +27 -153
  131. package/src/reachability/index.ts +1 -15
  132. package/src/reachability/reachabilityPeerConnection.ts +1 -3
  133. package/src/reactions/reactions.type.ts +0 -1
  134. package/src/reconnection-manager/index.ts +1 -0
  135. package/src/webinar/index.ts +6 -265
  136. package/test/unit/spec/annotation/index.ts +7 -69
  137. package/test/unit/spec/interceptors/locusRouteToken.ts +0 -44
  138. package/test/unit/spec/locus-info/controlsUtils.js +1 -56
  139. package/test/unit/spec/locus-info/index.js +90 -1457
  140. package/test/unit/spec/media/MediaConnectionAwaiter.ts +1 -41
  141. package/test/unit/spec/media/properties.ts +3 -12
  142. package/test/unit/spec/meeting/in-meeting-actions.ts +2 -8
  143. package/test/unit/spec/meeting/index.js +128 -981
  144. package/test/unit/spec/meeting/request.js +0 -70
  145. package/test/unit/spec/meeting/utils.js +26 -438
  146. package/test/unit/spec/meetings/index.js +33 -845
  147. package/test/unit/spec/meetings/utils.js +1 -51
  148. package/test/unit/spec/member/index.js +4 -28
  149. package/test/unit/spec/member/util.js +27 -65
  150. package/test/unit/spec/multistream/mediaRequestManager.ts +85 -2
  151. package/test/unit/spec/multistream/remoteMediaManager.ts +0 -30
  152. package/test/unit/spec/multistream/sendSlotManager.ts +36 -135
  153. package/test/unit/spec/reachability/clusterReachability.ts +1 -125
  154. package/test/unit/spec/reachability/index.ts +3 -26
  155. package/test/unit/spec/reconnection-manager/index.js +8 -4
  156. package/test/unit/spec/webinar/index.ts +37 -534
  157. package/dist/aiEnableRequest/index.js +0 -184
  158. package/dist/aiEnableRequest/index.js.map +0 -1
  159. package/dist/aiEnableRequest/utils.js +0 -36
  160. package/dist/aiEnableRequest/utils.js.map +0 -1
  161. package/dist/hashTree/constants.js +0 -22
  162. package/dist/hashTree/constants.js.map +0 -1
  163. package/dist/hashTree/hashTree.js +0 -533
  164. package/dist/hashTree/hashTree.js.map +0 -1
  165. package/dist/hashTree/utils.js +0 -69
  166. package/dist/hashTree/utils.js.map +0 -1
  167. package/dist/interceptors/constant.js +0 -12
  168. package/dist/interceptors/constant.js.map +0 -1
  169. package/dist/interceptors/dataChannelAuthToken.js +0 -290
  170. package/dist/interceptors/dataChannelAuthToken.js.map +0 -1
  171. package/dist/interceptors/utils.js +0 -27
  172. package/dist/interceptors/utils.js.map +0 -1
  173. package/dist/types/aiEnableRequest/index.d.ts +0 -5
  174. package/dist/types/aiEnableRequest/utils.d.ts +0 -2
  175. package/dist/types/hashTree/constants.d.ts +0 -9
  176. package/dist/types/hashTree/hashTree.d.ts +0 -136
  177. package/dist/types/hashTree/utils.d.ts +0 -22
  178. package/dist/types/interceptors/constant.d.ts +0 -5
  179. package/dist/types/interceptors/dataChannelAuthToken.d.ts +0 -43
  180. package/dist/types/interceptors/utils.d.ts +0 -1
  181. package/dist/types/webinar/utils.d.ts +0 -6
  182. package/dist/webinar/utils.js +0 -25
  183. package/dist/webinar/utils.js.map +0 -1
  184. package/src/aiEnableRequest/README.md +0 -84
  185. package/src/aiEnableRequest/index.ts +0 -170
  186. package/src/aiEnableRequest/utils.ts +0 -25
  187. package/src/hashTree/constants.ts +0 -10
  188. package/src/hashTree/hashTree.ts +0 -480
  189. package/src/hashTree/utils.ts +0 -62
  190. package/src/interceptors/constant.ts +0 -6
  191. package/src/interceptors/dataChannelAuthToken.ts +0 -170
  192. package/src/interceptors/utils.ts +0 -16
  193. package/src/webinar/utils.ts +0 -16
  194. package/test/unit/spec/aiEnableRequest/index.ts +0 -981
  195. package/test/unit/spec/aiEnableRequest/utils.ts +0 -130
  196. package/test/unit/spec/hashTree/hashTree.ts +0 -721
  197. package/test/unit/spec/hashTree/hashTreeParser.ts +0 -3670
  198. package/test/unit/spec/hashTree/utils.ts +0 -140
  199. package/test/unit/spec/interceptors/dataChannelAuthToken.ts +0 -210
  200. package/test/unit/spec/interceptors/utils.ts +0 -75
  201. package/test/unit/spec/webinar/utils.ts +0 -39
@@ -115,7 +115,6 @@ describe('plugin-meetings', () => {
115
115
  });
116
116
 
117
117
  describe('#changeVideoLayout', () => {
118
-
119
118
  const locusUrl = 'locusURL';
120
119
  const deviceUrl = 'deviceUrl';
121
120
  const layoutType = 'Equal';
@@ -919,73 +918,4 @@ describe('plugin-meetings', () => {
919
918
  });
920
919
  });
921
920
  });
922
-
923
- describe('#fetchDatachannelToken', () => {
924
- const locusUrl = 'https://locus.example.com/locus/api/v1/loci/123';
925
- const participantId = 'participant-123';
926
-
927
- beforeEach(() => {
928
- sinon.restore();
929
- locusDeltaRequestSpy = sinon.stub(meetingsRequest, 'locusDeltaRequest');
930
- });
931
-
932
- it('sends GET request to regular datachannel token endpoint', async () => {
933
- locusDeltaRequestSpy.resolves({body: {}});
934
-
935
- await meetingsRequest.fetchDatachannelToken({
936
- locusUrl,
937
- requestingParticipantId: participantId,
938
- isPracticeSession: false,
939
- });
940
-
941
- assert.calledOnceWithExactly(locusDeltaRequestSpy, {
942
- method: 'GET',
943
- uri: `${locusUrl}/participant/${participantId}/datachannel/token`,
944
- });
945
- });
946
-
947
- it('sends GET request to practice session datachannel token endpoint', async () => {
948
- locusDeltaRequestSpy.resolves({body: {}});
949
-
950
- await meetingsRequest.fetchDatachannelToken({
951
- locusUrl,
952
- requestingParticipantId: participantId,
953
- isPracticeSession: true,
954
- });
955
-
956
- assert.calledOnceWithExactly(locusDeltaRequestSpy, {
957
- method: 'GET',
958
- uri: `${locusUrl}/participant/${participantId}/practiceSession/datachannel/token`,
959
- });
960
- });
961
-
962
- it('rejects when locusUrl or participantId is missing', async () => {
963
- await assert.isRejected(
964
- meetingsRequest.fetchDatachannelToken({
965
- locusUrl: null,
966
- requestingParticipantId: participantId,
967
- }),
968
- /locusUrl and participantId are required/
969
- );
970
-
971
- await assert.isRejected(
972
- meetingsRequest.fetchDatachannelToken({
973
- locusUrl,
974
- requestingParticipantId: null,
975
- }),
976
- /locusUrl and participantId are required/
977
- );
978
- });
979
-
980
- it('returns null when locusDeltaRequest fails', async () => {
981
- locusDeltaRequestSpy.rejects(new Error('network error'));
982
-
983
- const result = await meetingsRequest.fetchDatachannelToken({
984
- locusUrl,
985
- requestingParticipantId: participantId,
986
- });
987
-
988
- assert.equal(result, null);
989
- });
990
- });
991
921
  });
@@ -11,7 +11,6 @@ import MockWebex from '@webex/test-helper-mock-webex';
11
11
  import * as BrowserDetectionModule from '@webex/plugin-meetings/src/common/browser-detection';
12
12
  import PasswordError from '@webex/plugin-meetings/src/common/errors/password-error';
13
13
  import CaptchaError from '@webex/plugin-meetings/src/common/errors/captcha-error';
14
- import {ServerRoles} from '@webex/plugin-meetings/src/member/types';
15
14
 
16
15
  describe('plugin-meetings', () => {
17
16
  let webex;
@@ -54,18 +53,16 @@ describe('plugin-meetings', () => {
54
53
  meeting.unsetPeerConnections = sinon.stub();
55
54
  meeting.reconnectionManager = {cleanUp: sinon.stub()};
56
55
  meeting.stopKeepAlive = sinon.stub();
57
- meeting.cleanupLLMConneciton = sinon.stub().resolves();
56
+ meeting.updateLLMConnection = sinon.stub();
58
57
  meeting.breakouts = {cleanUp: sinon.stub()};
59
- meeting.webinar = {cleanUp: sinon.stub()};
60
58
  meeting.annotaion = {cleanUp: sinon.stub()};
61
59
  meeting.getWebexObject = sinon.stub().returns(webex);
62
60
  meeting.simultaneousInterpretation = {cleanUp: sinon.stub()};
63
61
  meeting.trigger = sinon.stub();
64
62
  meeting.webex = webex;
65
63
  meeting.webex.internal.newMetrics.callDiagnosticMetrics =
66
- meeting.webex.internal.newMetrics.callDiagnosticMetrics || {};
67
- meeting.webex.internal.newMetrics.callDiagnosticMetrics.clearEventLimitsForCorrelationId =
68
- sinon.stub();
64
+ meeting.webex.internal.newMetrics.callDiagnosticMetrics || {};
65
+ meeting.webex.internal.newMetrics.callDiagnosticMetrics.clearEventLimitsForCorrelationId = sinon.stub();
69
66
  });
70
67
 
71
68
  afterEach(() => {
@@ -86,7 +83,7 @@ describe('plugin-meetings', () => {
86
83
  assert.calledOnce(meeting.unsetPeerConnections);
87
84
  assert.calledOnce(meeting.reconnectionManager.cleanUp);
88
85
  assert.calledOnce(meeting.stopKeepAlive);
89
- assert.calledOnceWithExactly(meeting.cleanupLLMConneciton, {throwOnError: false});
86
+ assert.calledOnce(meeting.updateLLMConnection);
90
87
  assert.calledOnce(meeting.breakouts.cleanUp);
91
88
  assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
92
89
  assert.calledOnce(webex.internal.device.meetingEnded);
@@ -107,7 +104,7 @@ describe('plugin-meetings', () => {
107
104
  assert.calledOnce(meeting.unsetPeerConnections);
108
105
  assert.calledOnce(meeting.reconnectionManager.cleanUp);
109
106
  assert.calledOnce(meeting.stopKeepAlive);
110
- assert.notCalled(meeting.cleanupLLMConneciton);
107
+ assert.notCalled(meeting.updateLLMConnection);
111
108
  assert.calledOnce(meeting.breakouts.cleanUp);
112
109
  assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
113
110
  assert.calledOnce(webex.internal.device.meetingEnded);
@@ -127,7 +124,7 @@ describe('plugin-meetings', () => {
127
124
  assert.calledOnce(meeting.unsetPeerConnections);
128
125
  assert.calledOnce(meeting.reconnectionManager.cleanUp);
129
126
  assert.calledOnce(meeting.stopKeepAlive);
130
- assert.notCalled(meeting.cleanupLLMConneciton);
127
+ assert.notCalled(meeting.updateLLMConnection);
131
128
  assert.calledOnce(meeting.breakouts.cleanUp);
132
129
  assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
133
130
  assert.calledOnce(webex.internal.device.meetingEnded);
@@ -248,11 +245,7 @@ describe('plugin-meetings', () => {
248
245
  const response = MeetingUtil.updateLocusFromApiResponse(meeting, originalResponse);
249
246
 
250
247
  assert.deepEqual(response, originalResponse);
251
- assert.calledOnceWithExactly(
252
- meeting.locusInfo.handleLocusAPIResponse,
253
- meeting,
254
- originalResponse.body
255
- );
248
+ assert.calledOnceWithExactly(meeting.locusInfo.handleLocusAPIResponse, meeting, originalResponse.body);
256
249
  });
257
250
 
258
251
  it('should handle locus being missing from the response', () => {
@@ -368,8 +361,8 @@ describe('plugin-meetings', () => {
368
361
  describe('remoteUpdateAudioVideo', () => {
369
362
  it('#Should call meetingRequest.locusMediaRequest with correct parameters and return the full response', async () => {
370
363
  const fakeResponse = {
371
- body: {locus: {url: 'locusUrl'}},
372
- headers: {},
364
+ body: { locus: { url: 'locusUrl'}},
365
+ headers: { },
373
366
  };
374
367
  const meeting = {
375
368
  id: 'meeting-id',
@@ -487,11 +480,6 @@ describe('plugin-meetings', () => {
487
480
  identifiers: {
488
481
  trackingId: 'trackingId',
489
482
  },
490
- eventData: {
491
- hasMismatchedSocket: false,
492
- mercurySocketUrl: '',
493
- deviceSocketUrl: 'ws://example.com',
494
- },
495
483
  },
496
484
  options: {
497
485
  meetingId: meeting.id,
@@ -661,26 +649,21 @@ describe('plugin-meetings', () => {
661
649
  it('should post client event with error when join fails', async () => {
662
650
  const joinError = new Error('Join failed');
663
651
  meeting.meetingRequest.joinMeeting.rejects(joinError);
664
- meeting.meetingInfo = {meetingLookupUrl: 'test-lookup-url'};
652
+ meeting.meetingInfo = { meetingLookupUrl: 'test-lookup-url' };
665
653
 
666
654
  try {
667
655
  await MeetingUtil.joinMeeting(meeting, {});
668
656
  assert.fail('Expected joinMeeting to throw an error');
669
657
  } catch (error) {
670
658
  assert.equal(error, joinError);
671
-
659
+
672
660
  // Verify error client event was submitted
673
661
  assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
674
662
  name: 'client.locus.join.response',
675
663
  payload: {
676
- identifiers: {meetingLookupUrl: 'test-lookup-url'},
677
- eventData: {
678
- hasMismatchedSocket: false,
679
- mercurySocketUrl: '',
680
- deviceSocketUrl: 'ws://example.com',
681
- },
664
+ identifiers: { meetingLookupUrl: 'test-lookup-url' },
682
665
  },
683
- options: {meetingId: meeting.id, rawError: joinError},
666
+ options: { meetingId: meeting.id, rawError: joinError },
684
667
  });
685
668
  }
686
669
  });
@@ -738,7 +721,7 @@ describe('plugin-meetings', () => {
738
721
  assert.fail('Expected joinMeetingOptions to throw PasswordError');
739
722
  } catch (error) {
740
723
  assert.instanceOf(error, PasswordError);
741
-
724
+
742
725
  // Verify client event was submitted with error details
743
726
  assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
744
727
  name: 'client.meetinginfo.response',
@@ -776,7 +759,7 @@ describe('plugin-meetings', () => {
776
759
  assert.fail('Expected joinMeetingOptions to throw CaptchaError');
777
760
  } catch (error) {
778
761
  assert.instanceOf(error, CaptchaError);
779
-
762
+
780
763
  // Verify client event was submitted with error details
781
764
  assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
782
765
  name: 'client.meetinginfo.response',
@@ -938,104 +921,6 @@ describe('plugin-meetings', () => {
938
921
  });
939
922
  });
940
923
 
941
- describe('canAttendeeRequestAiAssistantEnabled', () => {
942
- it('returns false when user is a cohost', () => {
943
- assert.deepEqual(
944
- MeetingUtil.canAttendeeRequestAiAssistantEnabled(
945
- ['ATTENDEE_REQUEST_AI_ASSISTANT_ENABLED'],
946
- [ServerRoles.Cohost]
947
- ),
948
- false
949
- );
950
- });
951
-
952
- it('returns false when user is a moderator', () => {
953
- assert.deepEqual(
954
- MeetingUtil.canAttendeeRequestAiAssistantEnabled(
955
- ['ATTENDEE_REQUEST_AI_ASSISTANT_ENABLED'],
956
- [ServerRoles.Moderator]
957
- ),
958
- false
959
- );
960
- });
961
-
962
- it('returns false when user is both cohost and moderator', () => {
963
- assert.deepEqual(
964
- MeetingUtil.canAttendeeRequestAiAssistantEnabled(
965
- ['ATTENDEE_REQUEST_AI_ASSISTANT_ENABLED'],
966
- [ServerRoles.Cohost, ServerRoles.Moderator]
967
- ),
968
- false
969
- );
970
- });
971
-
972
- it('returns true when user is an attendee and display hint is present', () => {
973
- assert.deepEqual(
974
- MeetingUtil.canAttendeeRequestAiAssistantEnabled(
975
- ['ATTENDEE_REQUEST_AI_ASSISTANT_ENABLED'],
976
- []
977
- ),
978
- true
979
- );
980
- });
981
-
982
- it('returns true when user has other roles (not host/cohost) and display hint is present', () => {
983
- assert.deepEqual(
984
- MeetingUtil.canAttendeeRequestAiAssistantEnabled(
985
- ['ATTENDEE_REQUEST_AI_ASSISTANT_ENABLED'],
986
- ['SomeOtherRole']
987
- ),
988
- true
989
- );
990
- });
991
-
992
- it('returns false when user is an attendee but display hint is not present', () => {
993
- assert.deepEqual(MeetingUtil.canAttendeeRequestAiAssistantEnabled([], []), false);
994
- });
995
-
996
- it('returns false when user is an attendee with other display hints but not the AI assistant one', () => {
997
- assert.deepEqual(
998
- MeetingUtil.canAttendeeRequestAiAssistantEnabled(['SOME_OTHER_HINT', 'ANOTHER_HINT'], []),
999
- false
1000
- );
1001
- });
1002
-
1003
- it('returns false when host/cohost even if display hint is not present', () => {
1004
- assert.deepEqual(
1005
- MeetingUtil.canAttendeeRequestAiAssistantEnabled([], [ServerRoles.Cohost]),
1006
- false
1007
- );
1008
- assert.deepEqual(
1009
- MeetingUtil.canAttendeeRequestAiAssistantEnabled([], [ServerRoles.Moderator]),
1010
- false
1011
- );
1012
- });
1013
- });
1014
-
1015
- describe('attendeeRequestAiAssistantDeclinedAll', () => {
1016
- it('returns true when display hint is present', () => {
1017
- assert.isTrue(
1018
- MeetingUtil.attendeeRequestAiAssistantDeclinedAll([
1019
- 'ATTENDEE_REQUEST_AI_ASSISTANT_DECLINED_ALL',
1020
- ])
1021
- );
1022
- });
1023
-
1024
- it('returns false when display hint is not present', () => {
1025
- assert.isFalse(MeetingUtil.attendeeRequestAiAssistantDeclinedAll([]));
1026
- });
1027
-
1028
- it('returns false when display hint is absent among other hints', () => {
1029
- assert.isFalse(
1030
- MeetingUtil.attendeeRequestAiAssistantDeclinedAll(['SOME_OTHER_HINT', 'ANOTHER_HINT'])
1031
- );
1032
- });
1033
-
1034
- it('returns false when called with no arguments', () => {
1035
- assert.isFalse(MeetingUtil.attendeeRequestAiAssistantDeclinedAll());
1036
- });
1037
- });
1038
-
1039
924
  describe('bothLeaveAndEndMeetingAvailable', () => {
1040
925
  it('works as expected', () => {
1041
926
  assert.deepEqual(
@@ -1054,46 +939,6 @@ describe('plugin-meetings', () => {
1054
939
  });
1055
940
  });
1056
941
 
1057
- describe('requireHostEndMeetingBeforeLeave', () => {
1058
- it('works as expected', () => {
1059
- assert.deepEqual(
1060
- MeetingUtil.requireHostEndMeetingBeforeLeave(['REQUIRE_HOST_END_MEETING_BEFORE_LEAVE']),
1061
- true
1062
- );
1063
- assert.deepEqual(
1064
- MeetingUtil.requireHostEndMeetingBeforeLeave([
1065
- 'LEAVE_TRANSFER_HOST_END_MEETING',
1066
- 'END_MEETING',
1067
- ]),
1068
- false
1069
- );
1070
- assert.deepEqual(
1071
- MeetingUtil.requireHostEndMeetingBeforeLeave([
1072
- 'REQUIRE_HOST_END_MEETING_BEFORE_LEAVE',
1073
- 'END_MEETING',
1074
- ]),
1075
- true
1076
- );
1077
- assert.deepEqual(
1078
- MeetingUtil.requireHostEndMeetingBeforeLeave([
1079
- 'REQUIRE_HOST_END_MEETING_BEFORE_LEAVE',
1080
- 'LEAVE_MEETING',
1081
- ]),
1082
- true
1083
- );
1084
- assert.deepEqual(
1085
- MeetingUtil.requireHostEndMeetingBeforeLeave([
1086
- 'REQUIRE_HOST_END_MEETING_BEFORE_LEAVE',
1087
- 'LEAVE_MEETING',
1088
- 'END_MEETING',
1089
- ]),
1090
- true
1091
- );
1092
- assert.deepEqual(MeetingUtil.requireHostEndMeetingBeforeLeave(['END_MEETING']), true);
1093
- assert.deepEqual(MeetingUtil.requireHostEndMeetingBeforeLeave([]), false);
1094
- });
1095
- });
1096
-
1097
942
  describe('canUserLock', () => {
1098
943
  it('works as expected', () => {
1099
944
  assert.deepEqual(
@@ -1127,18 +972,15 @@ describe('plugin-meetings', () => {
1127
972
  {functionName: 'canStartManualCaption', displayHint: 'MANUAL_CAPTION_START'},
1128
973
  {functionName: 'canStopManualCaption', displayHint: 'MANUAL_CAPTION_STOP'},
1129
974
 
1130
- {functionName: 'isLocalRecordingStarted', displayHint: 'LOCAL_RECORDING_STATUS_STARTED'},
975
+ {functionName: 'isLocalRecordingStarted',displayHint:'LOCAL_RECORDING_STATUS_STARTED'},
1131
976
  {functionName: 'isLocalRecordingStopped', displayHint: 'LOCAL_RECORDING_STATUS_STOPPED'},
1132
977
  {functionName: 'isLocalRecordingPaused', displayHint: 'LOCAL_RECORDING_STATUS_PAUSED'},
1133
- {functionName: 'isLocalStreamingStarted', displayHint: 'STREAMING_STATUS_STARTED'},
978
+ {functionName: 'isLocalStreamingStarted',displayHint:'STREAMING_STATUS_STARTED'},
1134
979
  {functionName: 'isLocalStreamingStopped', displayHint: 'STREAMING_STATUS_STOPPED'},
1135
980
 
1136
981
  {functionName: 'isManualCaptionActive', displayHint: 'MANUAL_CAPTION_STATUS_ACTIVE'},
1137
982
 
1138
- {
1139
- functionName: 'isSpokenLanguageAutoDetectionEnabled',
1140
- displayHint: 'SPOKEN_LANGUAGE_AUTO_DETECTION_ENABLED',
1141
- },
983
+ {functionName: 'isSpokenLanguageAutoDetectionEnabled', displayHint: 'SPOKEN_LANGUAGE_AUTO_DETECTION_ENABLED'},
1142
984
 
1143
985
  {functionName: 'isWebexAssistantActive', displayHint: 'WEBEX_ASSISTANT_STATUS_ACTIVE'},
1144
986
  {functionName: 'canViewCaptionPanel', displayHint: 'ENABLE_CAPTION_PANEL'},
@@ -1604,9 +1446,11 @@ describe('plugin-meetings', () => {
1604
1446
  id: 'selfId123',
1605
1447
  },
1606
1448
  },
1607
- metaData: {id: 'some hash tree metadata'},
1608
1449
  dataSets: [{name: 'dataset1', url: 'http://dataset.com'}],
1609
- mediaConnections: [{mediaId: 'mediaId456'}, {someOtherField: 'value'}],
1450
+ mediaConnections: [
1451
+ {mediaId: 'mediaId456'},
1452
+ {someOtherField: 'value'},
1453
+ ],
1610
1454
  },
1611
1455
  };
1612
1456
  });
@@ -1622,7 +1466,6 @@ describe('plugin-meetings', () => {
1622
1466
  locusId: '12345',
1623
1467
  selfId: 'selfId123',
1624
1468
  mediaId: 'mediaId456',
1625
- metadata: {id: 'some hash tree metadata'},
1626
1469
  });
1627
1470
  });
1628
1471
 
@@ -1652,275 +1495,20 @@ describe('plugin-meetings', () => {
1652
1495
  locusUrl: 'https://locus-a.wbx2.com/locus/api/v1/loci/12345',
1653
1496
  locusId: '12345',
1654
1497
  selfId: 'selfId123',
1655
- metadata: {id: 'some hash tree metadata'},
1656
1498
  });
1657
1499
  assert.isUndefined(result.mediaId);
1658
1500
  });
1659
1501
 
1660
1502
  it('handles mediaConnections without mediaId', () => {
1661
- response.body.mediaConnections = [{someField: 'value1'}, {anotherField: 'value2'}];
1503
+ response.body.mediaConnections = [
1504
+ {someField: 'value1'},
1505
+ {anotherField: 'value2'},
1506
+ ];
1662
1507
 
1663
1508
  const result = MeetingUtil.parseLocusJoin(response);
1664
1509
 
1665
1510
  assert.isUndefined(result.mediaId);
1666
1511
  });
1667
1512
  });
1668
-
1669
- describe('#sanitizeWebSocketUrl', () => {
1670
- it('extracts protocol, host, and pathname from URL', () => {
1671
- const url = 'wss://example.com:443/mercury/path?token=secret&key=value#fragment';
1672
- const result = MeetingUtil.sanitizeWebSocketUrl(url);
1673
-
1674
- assert.equal(result, 'wss://example.com:443/mercury/path');
1675
- });
1676
-
1677
- it('handles URL without query string or hash', () => {
1678
- const url = 'wss://example.com/path';
1679
- const result = MeetingUtil.sanitizeWebSocketUrl(url);
1680
-
1681
- assert.equal(result, 'wss://example.com/path');
1682
- });
1683
-
1684
- it('removes authentication from URL', () => {
1685
- const url = 'wss://user:password@example.com/path?token=secret';
1686
- const result = MeetingUtil.sanitizeWebSocketUrl(url);
1687
-
1688
- assert.equal(result, 'wss://example.com/path');
1689
- });
1690
-
1691
- it('returns empty string for null or undefined', () => {
1692
- assert.equal(MeetingUtil.sanitizeWebSocketUrl(null), '');
1693
- assert.equal(MeetingUtil.sanitizeWebSocketUrl(undefined), '');
1694
- });
1695
-
1696
- it('returns empty string for non-string input', () => {
1697
- assert.equal(MeetingUtil.sanitizeWebSocketUrl(123), '');
1698
- assert.equal(MeetingUtil.sanitizeWebSocketUrl({}), '');
1699
- });
1700
-
1701
- it('returns empty string for invalid URL', () => {
1702
- const result = MeetingUtil.sanitizeWebSocketUrl('not a valid url');
1703
-
1704
- assert.equal(result, '');
1705
- });
1706
-
1707
- it('handles URL without pathname', () => {
1708
- const url = 'wss://example.com?query=value';
1709
- const result = MeetingUtil.sanitizeWebSocketUrl(url);
1710
-
1711
- assert.equal(result, 'wss://example.com');
1712
- });
1713
- });
1714
-
1715
- describe('#_urlsPartiallyMatch', () => {
1716
- it('returns true when URLs match exactly (ignoring query and hash)', () => {
1717
- const url1 = 'wss://example.com:443/path?token=abc#fragment1';
1718
- const url2 = 'wss://example.com:443/path?token=xyz#fragment2';
1719
-
1720
- assert.isTrue(MeetingUtil._urlsPartiallyMatch(url1, url2));
1721
- });
1722
-
1723
- it('returns true when one URL is proxied and ends with the other', () => {
1724
- const url1 = 'wss://other.example.com/somepath/mercury.example.com/v1/path';
1725
- const url2 = 'wss://mercury.example.com/v1/path';
1726
-
1727
- assert.isTrue(MeetingUtil._urlsPartiallyMatch(url1, url2));
1728
- });
1729
-
1730
- it('returns true when the second URL is proxied', () => {
1731
- const url1 = 'wss://mercury.example.com/v1/path';
1732
- const url2 = 'wss://other.example.com/somepath/mercury.example.com/v1/path';
1733
-
1734
- assert.isTrue(MeetingUtil._urlsPartiallyMatch(url1, url2));
1735
- });
1736
-
1737
- it('returns false when hosts differ and no partial match', () => {
1738
- const url1 = 'wss://example1.com/path';
1739
- const url2 = 'wss://example2.com/path';
1740
-
1741
- assert.isFalse(MeetingUtil._urlsPartiallyMatch(url1, url2));
1742
- });
1743
-
1744
- it('returns false when pathnames differ and no partial match', () => {
1745
- const url1 = 'wss://example.com/path1';
1746
- const url2 = 'wss://example.com/path2';
1747
-
1748
- assert.isFalse(MeetingUtil._urlsPartiallyMatch(url1, url2));
1749
- });
1750
-
1751
- it('returns false when either URL is null or undefined', () => {
1752
- const url = 'wss://example.com/path';
1753
-
1754
- assert.isFalse(MeetingUtil._urlsPartiallyMatch(null, url));
1755
- assert.isFalse(MeetingUtil._urlsPartiallyMatch(url, null));
1756
- assert.isFalse(MeetingUtil._urlsPartiallyMatch(undefined, url));
1757
- assert.isFalse(MeetingUtil._urlsPartiallyMatch(url, undefined));
1758
- });
1759
-
1760
- it('returns false when both URLs are null', () => {
1761
- assert.isFalse(MeetingUtil._urlsPartiallyMatch(null, null));
1762
- });
1763
-
1764
- it('returns false when URL parsing fails', () => {
1765
- const url1 = 'invalid url';
1766
- const url2 = 'wss://example.com/path';
1767
-
1768
- assert.isFalse(MeetingUtil._urlsPartiallyMatch(url1, url2));
1769
- });
1770
- });
1771
-
1772
- describe('#getSocketUrlInfo', () => {
1773
- it('returns socket URL info when URLs differ', () => {
1774
- const testWebex = {
1775
- internal: {
1776
- mercury: {
1777
- socket: {
1778
- url: 'wss://mercury.example.com:443/path?token=abc',
1779
- },
1780
- },
1781
- device: {
1782
- webSocketUrl: 'wss://device.example.com:443/path?token=xyz',
1783
- },
1784
- },
1785
- };
1786
-
1787
- const result = MeetingUtil.getSocketUrlInfo(testWebex);
1788
-
1789
- assert.isTrue(result.hasMismatchedSocket);
1790
- assert.equal(result.mercurySocketUrl, 'wss://mercury.example.com:443/path');
1791
- assert.equal(result.deviceSocketUrl, 'wss://device.example.com:443/path');
1792
- });
1793
-
1794
- it('returns socket URL info when URLs match', () => {
1795
- const testWebex = {
1796
- internal: {
1797
- mercury: {
1798
- socket: {
1799
- url: 'wss://example.com:443/path?token=abc',
1800
- },
1801
- },
1802
- device: {
1803
- webSocketUrl: 'wss://example.com:443/path?token=xyz',
1804
- },
1805
- },
1806
- };
1807
-
1808
- const result = MeetingUtil.getSocketUrlInfo(testWebex);
1809
-
1810
- assert.isFalse(result.hasMismatchedSocket);
1811
- assert.equal(result.mercurySocketUrl, 'wss://example.com:443/path');
1812
- assert.equal(result.deviceSocketUrl, 'wss://example.com:443/path');
1813
- });
1814
-
1815
- it('returns hasMismatchedSocket as false when one URL is proxied (partial match)', () => {
1816
- const testWebex = {
1817
- internal: {
1818
- mercury: {
1819
- socket: {
1820
- url: 'wss://other.example.com/somepath/mercury.example.com/v1/apps/wx2/registrations/00000000-0000-0000-0000-000000000000/messages',
1821
- },
1822
- },
1823
- device: {
1824
- webSocketUrl:
1825
- 'wss://mercury.example.com/v1/apps/wx2/registrations/00000000-0000-0000-0000-000000000000/messages',
1826
- },
1827
- },
1828
- };
1829
-
1830
- const result = MeetingUtil.getSocketUrlInfo(testWebex);
1831
-
1832
- assert.isFalse(result.hasMismatchedSocket);
1833
- assert.equal(
1834
- result.mercurySocketUrl,
1835
- 'wss://other.example.com/somepath/mercury.example.com/v1/apps/wx2/registrations/00000000-0000-0000-0000-000000000000/messages'
1836
- );
1837
- assert.equal(
1838
- result.deviceSocketUrl,
1839
- 'wss://mercury.example.com/v1/apps/wx2/registrations/00000000-0000-0000-0000-000000000000/messages'
1840
- );
1841
- });
1842
-
1843
- it('returns false for hasMismatchedSocket when mercury socket URL is missing', () => {
1844
- const testWebex = {
1845
- internal: {
1846
- mercury: {
1847
- socket: {},
1848
- },
1849
- device: {
1850
- webSocketUrl: 'wss://device.example.com:443/path',
1851
- },
1852
- },
1853
- };
1854
-
1855
- const result = MeetingUtil.getSocketUrlInfo(testWebex);
1856
-
1857
- assert.isFalse(result.hasMismatchedSocket);
1858
- assert.equal(result.mercurySocketUrl, '');
1859
- assert.equal(result.deviceSocketUrl, 'wss://device.example.com:443/path');
1860
- });
1861
-
1862
- it('returns false for hasMismatchedSocket when device socket URL is missing', () => {
1863
- const testWebex = {
1864
- internal: {
1865
- mercury: {
1866
- socket: {
1867
- url: 'wss://mercury.example.com:443/path',
1868
- },
1869
- },
1870
- device: {},
1871
- },
1872
- };
1873
-
1874
- const result = MeetingUtil.getSocketUrlInfo(testWebex);
1875
-
1876
- assert.isFalse(result.hasMismatchedSocket);
1877
- assert.equal(result.mercurySocketUrl, 'wss://mercury.example.com:443/path');
1878
- assert.equal(result.deviceSocketUrl, '');
1879
- });
1880
-
1881
- it('returns default values when webex object is missing properties', () => {
1882
- const testWebex = {
1883
- internal: {},
1884
- };
1885
-
1886
- const result = MeetingUtil.getSocketUrlInfo(testWebex);
1887
-
1888
- assert.isFalse(result.hasMismatchedSocket);
1889
- assert.equal(result.mercurySocketUrl, '');
1890
- assert.equal(result.deviceSocketUrl, '');
1891
- });
1892
-
1893
- it('handles error gracefully and returns default values', () => {
1894
- const testWebex = null;
1895
-
1896
- const result = MeetingUtil.getSocketUrlInfo(testWebex);
1897
-
1898
- assert.isFalse(result.hasMismatchedSocket);
1899
- assert.equal(result.mercurySocketUrl, '');
1900
- assert.equal(result.deviceSocketUrl, '');
1901
- });
1902
-
1903
- it('sanitizes URLs by removing query parameters', () => {
1904
- const testWebex = {
1905
- internal: {
1906
- mercury: {
1907
- socket: {
1908
- url: 'wss://mercury.example.com/path?secret=token123&key=value',
1909
- },
1910
- },
1911
- device: {
1912
- webSocketUrl: 'wss://device.example.com/path?secret=differenttoken&key=value',
1913
- },
1914
- },
1915
- };
1916
-
1917
- const result = MeetingUtil.getSocketUrlInfo(testWebex);
1918
-
1919
- assert.notInclude(result.mercurySocketUrl, 'secret');
1920
- assert.notInclude(result.mercurySocketUrl, 'token123');
1921
- assert.notInclude(result.deviceSocketUrl, 'secret');
1922
- assert.notInclude(result.deviceSocketUrl, 'differenttoken');
1923
- });
1924
- });
1925
1513
  });
1926
1514
  });