@webex/plugin-meetings 3.8.1 → 3.9.0-multipleLLM.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 (317) hide show
  1. package/README.md +26 -13
  2. package/dist/breakouts/breakout.js +1 -1
  3. package/dist/breakouts/index.js +1 -1
  4. package/dist/constants.js +34 -3
  5. package/dist/constants.js.map +1 -1
  6. package/dist/controls-options-manager/enums.js +1 -0
  7. package/dist/controls-options-manager/enums.js.map +1 -1
  8. package/dist/controls-options-manager/types.js.map +1 -1
  9. package/dist/controls-options-manager/util.js +26 -0
  10. package/dist/controls-options-manager/util.js.map +1 -1
  11. package/dist/interpretation/index.js +1 -1
  12. package/dist/interpretation/siLanguage.js +1 -1
  13. package/dist/locus-info/controlsUtils.js +11 -3
  14. package/dist/locus-info/controlsUtils.js.map +1 -1
  15. package/dist/locus-info/index.js +107 -95
  16. package/dist/locus-info/index.js.map +1 -1
  17. package/dist/locus-info/parser.js +4 -1
  18. package/dist/locus-info/parser.js.map +1 -1
  19. package/dist/media/index.js +2 -2
  20. package/dist/media/index.js.map +1 -1
  21. package/dist/media/properties.js +53 -5
  22. package/dist/media/properties.js.map +1 -1
  23. package/dist/meeting/brbState.js +17 -14
  24. package/dist/meeting/brbState.js.map +1 -1
  25. package/dist/meeting/in-meeting-actions.js +13 -1
  26. package/dist/meeting/in-meeting-actions.js.map +1 -1
  27. package/dist/meeting/index.js +555 -296
  28. package/dist/meeting/index.js.map +1 -1
  29. package/dist/meeting/muteState.js +2 -5
  30. package/dist/meeting/muteState.js.map +1 -1
  31. package/dist/meeting/request.js +44 -0
  32. package/dist/meeting/request.js.map +1 -1
  33. package/dist/meeting/request.type.js.map +1 -1
  34. package/dist/{rtcMetrics/constants.js → meeting/type.js} +1 -5
  35. package/dist/meeting/type.js.map +1 -0
  36. package/dist/meeting/util.js +98 -13
  37. package/dist/meeting/util.js.map +1 -1
  38. package/dist/meeting-info/meeting-info-v2.js +29 -21
  39. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  40. package/dist/meetings/index.js +18 -10
  41. package/dist/meetings/index.js.map +1 -1
  42. package/dist/member/types.js.map +1 -1
  43. package/dist/members/collection.js +13 -0
  44. package/dist/members/collection.js.map +1 -1
  45. package/dist/members/index.js +53 -29
  46. package/dist/members/index.js.map +1 -1
  47. package/dist/members/request.js +3 -3
  48. package/dist/members/request.js.map +1 -1
  49. package/dist/members/util.js +25 -8
  50. package/dist/members/util.js.map +1 -1
  51. package/dist/metrics/constants.js +3 -1
  52. package/dist/metrics/constants.js.map +1 -1
  53. package/dist/multistream/mediaRequestManager.js +1 -1
  54. package/dist/multistream/mediaRequestManager.js.map +1 -1
  55. package/dist/multistream/remoteMedia.js +34 -5
  56. package/dist/multistream/remoteMedia.js.map +1 -1
  57. package/dist/multistream/remoteMediaGroup.js +42 -2
  58. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  59. package/dist/multistream/sendSlotManager.js +32 -2
  60. package/dist/multistream/sendSlotManager.js.map +1 -1
  61. package/dist/reachability/index.js +8 -13
  62. package/dist/reachability/index.js.map +1 -1
  63. package/dist/types/constants.d.ts +30 -0
  64. package/dist/types/controls-options-manager/enums.d.ts +2 -1
  65. package/dist/types/controls-options-manager/types.d.ts +4 -1
  66. package/dist/types/locus-info/index.d.ts +54 -10
  67. package/dist/types/media/properties.d.ts +21 -0
  68. package/dist/types/meeting/brbState.d.ts +0 -1
  69. package/dist/types/meeting/in-meeting-actions.d.ts +12 -0
  70. package/dist/types/meeting/index.d.ts +58 -20
  71. package/dist/types/meeting/request.d.ts +18 -1
  72. package/dist/types/meeting/request.type.d.ts +74 -0
  73. package/dist/types/meeting/type.d.ts +9 -0
  74. package/dist/types/meeting/util.d.ts +13 -3
  75. package/dist/types/meeting-info/meeting-info-v2.d.ts +6 -3
  76. package/dist/types/meetings/index.d.ts +3 -1
  77. package/dist/types/member/types.d.ts +1 -0
  78. package/dist/types/members/collection.d.ts +6 -0
  79. package/dist/types/members/index.d.ts +22 -9
  80. package/dist/types/members/request.d.ts +1 -1
  81. package/dist/types/members/util.d.ts +13 -6
  82. package/dist/types/metrics/constants.d.ts +2 -0
  83. package/dist/types/multistream/remoteMedia.d.ts +20 -1
  84. package/dist/types/multistream/remoteMediaGroup.d.ts +11 -0
  85. package/dist/types/multistream/sendSlotManager.d.ts +16 -0
  86. package/dist/types/reachability/index.d.ts +2 -2
  87. package/dist/webinar/index.js +1 -1
  88. package/package.json +24 -25
  89. package/src/constants.ts +34 -2
  90. package/src/controls-options-manager/enums.ts +1 -0
  91. package/src/controls-options-manager/types.ts +6 -1
  92. package/src/controls-options-manager/util.ts +31 -0
  93. package/src/locus-info/controlsUtils.ts +15 -0
  94. package/src/locus-info/index.ts +174 -96
  95. package/src/locus-info/parser.ts +5 -1
  96. package/src/media/index.ts +2 -2
  97. package/src/media/properties.ts +43 -0
  98. package/src/meeting/brbState.ts +13 -9
  99. package/src/meeting/in-meeting-actions.ts +25 -0
  100. package/src/meeting/index.ts +362 -75
  101. package/src/meeting/muteState.ts +2 -6
  102. package/src/meeting/request.ts +39 -0
  103. package/src/meeting/request.type.ts +64 -0
  104. package/src/meeting/type.ts +9 -0
  105. package/src/meeting/util.ts +114 -22
  106. package/src/meeting-info/meeting-info-v2.ts +24 -5
  107. package/src/meetings/index.ts +12 -5
  108. package/src/member/types.ts +1 -0
  109. package/src/members/collection.ts +11 -0
  110. package/src/members/index.ts +51 -15
  111. package/src/members/request.ts +2 -2
  112. package/src/members/util.ts +34 -6
  113. package/src/metrics/constants.ts +2 -0
  114. package/src/multistream/mediaRequestManager.ts +7 -7
  115. package/src/multistream/remoteMedia.ts +34 -4
  116. package/src/multistream/remoteMediaGroup.ts +37 -2
  117. package/src/multistream/sendSlotManager.ts +34 -2
  118. package/src/reachability/index.ts +8 -16
  119. package/test/unit/spec/controls-options-manager/util.js +58 -0
  120. package/test/unit/spec/locus-info/controlsUtils.js +52 -0
  121. package/test/unit/spec/locus-info/index.js +270 -97
  122. package/test/unit/spec/locus-info/parser.js +3 -2
  123. package/test/unit/spec/media/index.ts +107 -0
  124. package/test/unit/spec/media/properties.ts +137 -0
  125. package/test/unit/spec/meeting/brbState.ts +23 -4
  126. package/test/unit/spec/meeting/in-meeting-actions.ts +12 -0
  127. package/test/unit/spec/meeting/index.js +1194 -97
  128. package/test/unit/spec/meeting/muteState.js +32 -6
  129. package/test/unit/spec/meeting/request.js +92 -0
  130. package/test/unit/spec/meeting/utils.js +167 -17
  131. package/test/unit/spec/meeting-info/meetinginfov2.js +8 -3
  132. package/test/unit/spec/meetings/index.js +12 -1
  133. package/test/unit/spec/members/collection.js +120 -0
  134. package/test/unit/spec/members/index.js +140 -12
  135. package/test/unit/spec/members/request.js +57 -2
  136. package/test/unit/spec/members/utils.js +139 -17
  137. package/test/unit/spec/multistream/mediaRequestManager.ts +19 -6
  138. package/test/unit/spec/multistream/remoteMedia.ts +66 -2
  139. package/test/unit/spec/multistream/sendSlotManager.ts +59 -0
  140. package/test/unit/spec/reachability/index.ts +160 -9
  141. package/dist/annotation/annotation.types.d.ts +0 -42
  142. package/dist/annotation/constants.d.ts +0 -31
  143. package/dist/annotation/index.d.ts +0 -117
  144. package/dist/breakouts/breakout.d.ts +0 -8
  145. package/dist/breakouts/collection.d.ts +0 -5
  146. package/dist/breakouts/edit-lock-error.d.ts +0 -15
  147. package/dist/breakouts/events.d.ts +0 -8
  148. package/dist/breakouts/index.d.ts +0 -5
  149. package/dist/breakouts/request.d.ts +0 -22
  150. package/dist/breakouts/utils.d.ts +0 -15
  151. package/dist/common/browser-detection.d.ts +0 -9
  152. package/dist/common/collection.d.ts +0 -48
  153. package/dist/common/config.d.ts +0 -2
  154. package/dist/common/errors/captcha-error.d.ts +0 -15
  155. package/dist/common/errors/intent-to-join.d.ts +0 -16
  156. package/dist/common/errors/join-meeting.d.ts +0 -17
  157. package/dist/common/errors/media.d.ts +0 -15
  158. package/dist/common/errors/no-meeting-info.d.ts +0 -14
  159. package/dist/common/errors/parameter.d.ts +0 -15
  160. package/dist/common/errors/password-error.d.ts +0 -15
  161. package/dist/common/errors/permission.d.ts +0 -14
  162. package/dist/common/errors/reclaim-host-role-error.d.ts +0 -60
  163. package/dist/common/errors/reclaim-host-role-error.js +0 -158
  164. package/dist/common/errors/reclaim-host-role-error.js.map +0 -1
  165. package/dist/common/errors/reclaim-host-role-errors.d.ts +0 -60
  166. package/dist/common/errors/reconnection-in-progress.d.ts +0 -9
  167. package/dist/common/errors/reconnection-in-progress.js +0 -35
  168. package/dist/common/errors/reconnection-in-progress.js.map +0 -1
  169. package/dist/common/errors/reconnection.d.ts +0 -15
  170. package/dist/common/errors/stats.d.ts +0 -15
  171. package/dist/common/errors/webex-errors.d.ts +0 -81
  172. package/dist/common/errors/webex-meetings-error.d.ts +0 -20
  173. package/dist/common/events/events-scope.d.ts +0 -17
  174. package/dist/common/events/events.d.ts +0 -12
  175. package/dist/common/events/trigger-proxy.d.ts +0 -2
  176. package/dist/common/events/util.d.ts +0 -2
  177. package/dist/common/logs/logger-config.d.ts +0 -2
  178. package/dist/common/logs/logger-proxy.d.ts +0 -2
  179. package/dist/common/logs/request.d.ts +0 -34
  180. package/dist/common/queue.d.ts +0 -32
  181. package/dist/config.d.ts +0 -73
  182. package/dist/constants.d.ts +0 -952
  183. package/dist/controls-options-manager/constants.d.ts +0 -4
  184. package/dist/controls-options-manager/enums.d.ts +0 -5
  185. package/dist/controls-options-manager/index.d.ts +0 -120
  186. package/dist/controls-options-manager/types.d.ts +0 -43
  187. package/dist/controls-options-manager/util.d.ts +0 -7
  188. package/dist/index.d.ts +0 -4
  189. package/dist/interceptors/index.d.ts +0 -2
  190. package/dist/interceptors/locusRetry.d.ts +0 -27
  191. package/dist/interpretation/collection.d.ts +0 -5
  192. package/dist/interpretation/index.d.ts +0 -5
  193. package/dist/interpretation/siLanguage.d.ts +0 -5
  194. package/dist/locus-info/controlsUtils.d.ts +0 -2
  195. package/dist/locus-info/embeddedAppsUtils.d.ts +0 -2
  196. package/dist/locus-info/fullState.d.ts +0 -2
  197. package/dist/locus-info/hostUtils.d.ts +0 -2
  198. package/dist/locus-info/index.d.ts +0 -269
  199. package/dist/locus-info/infoUtils.d.ts +0 -2
  200. package/dist/locus-info/mediaSharesUtils.d.ts +0 -2
  201. package/dist/locus-info/parser.d.ts +0 -212
  202. package/dist/locus-info/selfUtils.d.ts +0 -2
  203. package/dist/media/index.d.ts +0 -32
  204. package/dist/media/properties.d.ts +0 -108
  205. package/dist/media/util.d.ts +0 -2
  206. package/dist/mediaQualityMetrics/config.d.ts +0 -233
  207. package/dist/mediaQualityMetrics/config.js +0 -513
  208. package/dist/mediaQualityMetrics/config.js.map +0 -1
  209. package/dist/meeting/effectsState.d.ts +0 -42
  210. package/dist/meeting/effectsState.js +0 -260
  211. package/dist/meeting/effectsState.js.map +0 -1
  212. package/dist/meeting/in-meeting-actions.d.ts +0 -79
  213. package/dist/meeting/index.d.ts +0 -1622
  214. package/dist/meeting/locusMediaRequest.d.ts +0 -74
  215. package/dist/meeting/muteState.d.ts +0 -116
  216. package/dist/meeting/request.d.ts +0 -257
  217. package/dist/meeting/request.type.d.ts +0 -11
  218. package/dist/meeting/state.d.ts +0 -9
  219. package/dist/meeting/util.d.ts +0 -2
  220. package/dist/meeting/voicea-meeting.d.ts +0 -16
  221. package/dist/meeting-info/collection.d.ts +0 -20
  222. package/dist/meeting-info/index.d.ts +0 -57
  223. package/dist/meeting-info/meeting-info-v2.d.ts +0 -93
  224. package/dist/meeting-info/request.d.ts +0 -22
  225. package/dist/meeting-info/util.d.ts +0 -2
  226. package/dist/meeting-info/utilv2.d.ts +0 -2
  227. package/dist/meetings/collection.d.ts +0 -23
  228. package/dist/meetings/index.d.ts +0 -296
  229. package/dist/meetings/meetings.types.d.ts +0 -4
  230. package/dist/meetings/request.d.ts +0 -27
  231. package/dist/meetings/util.d.ts +0 -18
  232. package/dist/member/index.d.ts +0 -148
  233. package/dist/member/member.types.d.ts +0 -11
  234. package/dist/member/member.types.js +0 -18
  235. package/dist/member/member.types.js.map +0 -1
  236. package/dist/member/types.d.ts +0 -32
  237. package/dist/member/util.d.ts +0 -2
  238. package/dist/members/collection.d.ts +0 -24
  239. package/dist/members/index.d.ts +0 -308
  240. package/dist/members/request.d.ts +0 -58
  241. package/dist/members/types.d.ts +0 -25
  242. package/dist/members/util.d.ts +0 -2
  243. package/dist/metrics/config.d.ts +0 -169
  244. package/dist/metrics/config.js +0 -289
  245. package/dist/metrics/config.js.map +0 -1
  246. package/dist/metrics/constants.d.ts +0 -59
  247. package/dist/metrics/index.d.ts +0 -152
  248. package/dist/multistream/mediaRequestManager.d.ts +0 -119
  249. package/dist/multistream/receiveSlot.d.ts +0 -68
  250. package/dist/multistream/receiveSlotManager.d.ts +0 -56
  251. package/dist/multistream/remoteMedia.d.ts +0 -72
  252. package/dist/multistream/remoteMediaGroup.d.ts +0 -49
  253. package/dist/multistream/remoteMediaManager.d.ts +0 -300
  254. package/dist/multistream/sendSlotManager.d.ts +0 -69
  255. package/dist/networkQualityMonitor/index.d.ts +0 -70
  256. package/dist/networkQualityMonitor/index.js +0 -226
  257. package/dist/networkQualityMonitor/index.js.map +0 -1
  258. package/dist/peer-connection-manager/index.d.ts +0 -6
  259. package/dist/peer-connection-manager/index.js +0 -671
  260. package/dist/peer-connection-manager/index.js.map +0 -1
  261. package/dist/peer-connection-manager/util.d.ts +0 -6
  262. package/dist/peer-connection-manager/util.js +0 -110
  263. package/dist/peer-connection-manager/util.js.map +0 -1
  264. package/dist/personal-meeting-room/index.d.ts +0 -47
  265. package/dist/personal-meeting-room/request.d.ts +0 -14
  266. package/dist/personal-meeting-room/util.d.ts +0 -2
  267. package/dist/reachability/clusterReachability.d.ts +0 -109
  268. package/dist/reachability/index.d.ts +0 -139
  269. package/dist/reachability/request.d.ts +0 -35
  270. package/dist/reachability/util.d.ts +0 -8
  271. package/dist/reactions/constants.d.ts +0 -3
  272. package/dist/reactions/reactions.d.ts +0 -4
  273. package/dist/reactions/reactions.type.d.ts +0 -32
  274. package/dist/reconnection-manager/index.d.ts +0 -112
  275. package/dist/recording-controller/enums.d.ts +0 -7
  276. package/dist/recording-controller/index.d.ts +0 -193
  277. package/dist/recording-controller/util.d.ts +0 -13
  278. package/dist/roap/collection.d.ts +0 -10
  279. package/dist/roap/collection.js +0 -63
  280. package/dist/roap/collection.js.map +0 -1
  281. package/dist/roap/handler.d.ts +0 -47
  282. package/dist/roap/handler.js +0 -279
  283. package/dist/roap/handler.js.map +0 -1
  284. package/dist/roap/index.d.ts +0 -116
  285. package/dist/roap/request.d.ts +0 -35
  286. package/dist/roap/state.d.ts +0 -9
  287. package/dist/roap/state.js +0 -127
  288. package/dist/roap/state.js.map +0 -1
  289. package/dist/roap/turnDiscovery.d.ts +0 -81
  290. package/dist/roap/util.d.ts +0 -2
  291. package/dist/roap/util.js +0 -76
  292. package/dist/roap/util.js.map +0 -1
  293. package/dist/rtcMetrics/constants.d.ts +0 -4
  294. package/dist/rtcMetrics/constants.js.map +0 -1
  295. package/dist/rtcMetrics/index.d.ts +0 -61
  296. package/dist/rtcMetrics/index.js +0 -197
  297. package/dist/rtcMetrics/index.js.map +0 -1
  298. package/dist/statsAnalyzer/global.d.ts +0 -118
  299. package/dist/statsAnalyzer/global.js +0 -127
  300. package/dist/statsAnalyzer/global.js.map +0 -1
  301. package/dist/statsAnalyzer/index.d.ts +0 -193
  302. package/dist/statsAnalyzer/index.js +0 -1019
  303. package/dist/statsAnalyzer/index.js.map +0 -1
  304. package/dist/statsAnalyzer/mqaUtil.d.ts +0 -22
  305. package/dist/statsAnalyzer/mqaUtil.js +0 -181
  306. package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
  307. package/dist/transcription/index.d.ts +0 -64
  308. package/dist/types/common/errors/reconnection-in-progress.d.ts +0 -9
  309. package/dist/types/mediaQualityMetrics/config.d.ts +0 -241
  310. package/dist/types/networkQualityMonitor/index.d.ts +0 -70
  311. package/dist/types/rtcMetrics/constants.d.ts +0 -4
  312. package/dist/types/rtcMetrics/index.d.ts +0 -71
  313. package/dist/types/statsAnalyzer/global.d.ts +0 -36
  314. package/dist/types/statsAnalyzer/index.d.ts +0 -217
  315. package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
  316. package/dist/webinar/collection.d.ts +0 -16
  317. package/dist/webinar/index.d.ts +0 -5
@@ -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
 
@@ -826,4 +826,96 @@ describe('plugin-meetings', () => {
826
826
  });
827
827
  });
828
828
  });
829
+
830
+ describe('#synchronizeStage', () => {
831
+ [
832
+ ['an unset stage', {overrideDefault: false}],
833
+ [
834
+ 'a minimally set stage',
835
+ {
836
+ overrideDefault: true,
837
+ lockAttendeeViewOnStageOnly: false,
838
+ stageParameters: {
839
+ activeSpeakerProportion: 0.5,
840
+ showActiveSpeaker: {show: false, order: 0},
841
+ stageManagerType: 0,
842
+ },
843
+ },
844
+ ],
845
+ [
846
+ 'a fully set stage',
847
+ {
848
+ overrideDefault: true,
849
+ lockAttendeeViewOnStageOnly: true,
850
+ stageParameters: {
851
+ activeSpeakerProportion: 0.6,
852
+ importantParticipants: [
853
+ {mainCsi: 11111111, participantId: uuidv4(), order: 1},
854
+ {mainCsi: 22222222, participantId: uuidv4(), order: 2},
855
+ {mainCsi: 33333333, participantId: uuidv4(), order: 3},
856
+ {mainCsi: 44444444, participantId: uuidv4(), order: 4},
857
+ {mainCsi: 55555555, participantId: uuidv4(), order: 5},
858
+ {mainCsi: 66666666, participantId: uuidv4(), order: 6},
859
+ {mainCsi: 77777777, participantId: uuidv4(), order: 7},
860
+ {mainCsi: 88888888, participantId: uuidv4(), order: 8},
861
+ ],
862
+ showActiveSpeaker: {show: true, order: 0},
863
+ stageManagerType: 7,
864
+ },
865
+ customLayouts: {
866
+ background: {url: `https://test.wbx2.com/background/${uuidv4()}.jpg`},
867
+ logo: {url: `https://test.wbx2.com/logo/${uuidv4()}.png`, position: 'UpperMiddle'},
868
+ },
869
+ nameLabelStyle: {
870
+ accentColor: '#00A3FF',
871
+ background: {color: 'rgba(0, 163, 255, 1)'},
872
+ border: {color: 'rgba(0, 163, 255, 1)'},
873
+ content: {
874
+ displayName: {color: 'rgba(255, 255, 255, 0.95)'},
875
+ subtitle: {color: 'rgba(255, 255, 255, 0.7)'},
876
+ },
877
+ decoration: {color: 'rgba(255, 255, 255, 0.95)'},
878
+ fadeOut: {delay: 15},
879
+ type: 'PrimaryInverted',
880
+ },
881
+ },
882
+ ],
883
+ ].forEach(([description, videoLayout]) => {
884
+ it(`sends request to synchronize the stage with ${description} video layout`, async () => {
885
+ const locusUrl = `https://locus-test.wbx2.com/locus/api/v1/loci/${uuidv4()}`;
886
+
887
+ const synchronizePromise = meetingsRequest.synchronizeStage(locusUrl, videoLayout);
888
+
889
+ assert.exists(synchronizePromise.then);
890
+ await synchronizePromise;
891
+
892
+ checkRequest({
893
+ method: 'PATCH',
894
+ uri: `${locusUrl}/controls`,
895
+ body: {videoLayout},
896
+ });
897
+ });
898
+ });
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
+ });
829
921
  });
@@ -3,12 +3,14 @@ import sinon from 'sinon';
3
3
  import {assert} from '@webex/test-helper-chai';
4
4
  import Meetings from '@webex/plugin-meetings';
5
5
  import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
6
- import {LOCAL_SHARE_ERRORS} from '@webex/plugin-meetings/src/constants';
6
+ import {LOCAL_SHARE_ERRORS, PASSWORD_STATUS} from '@webex/plugin-meetings/src/constants';
7
7
  import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
8
8
  import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
9
9
  import {SELF_POLICY, IP_VERSION} from '@webex/plugin-meetings/src/constants';
10
10
  import MockWebex from '@webex/test-helper-mock-webex';
11
11
  import * as BrowserDetectionModule from '@webex/plugin-meetings/src/common/browser-detection';
12
+ import PasswordError from '@webex/plugin-meetings/src/common/errors/password-error';
13
+ import CaptchaError from '@webex/plugin-meetings/src/common/errors/captcha-error';
12
14
 
13
15
  describe('plugin-meetings', () => {
14
16
  let webex;
@@ -57,6 +59,10 @@ describe('plugin-meetings', () => {
57
59
  meeting.getWebexObject = sinon.stub().returns(webex);
58
60
  meeting.simultaneousInterpretation = {cleanUp: sinon.stub()};
59
61
  meeting.trigger = sinon.stub();
62
+ meeting.webex = webex;
63
+ meeting.webex.internal.newMetrics.callDiagnosticMetrics =
64
+ meeting.webex.internal.newMetrics.callDiagnosticMetrics || {};
65
+ meeting.webex.internal.newMetrics.callDiagnosticMetrics.clearEventLimitsForCorrelationId = sinon.stub();
60
66
  });
61
67
 
62
68
  afterEach(() => {
@@ -81,6 +87,10 @@ describe('plugin-meetings', () => {
81
87
  assert.calledOnce(meeting.breakouts.cleanUp);
82
88
  assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
83
89
  assert.calledOnce(webex.internal.device.meetingEnded);
90
+ assert.calledOnceWithExactly(
91
+ meeting.webex.internal.newMetrics.callDiagnosticMetrics.clearEventLimitsForCorrelationId,
92
+ meeting.correlationId
93
+ );
84
94
  });
85
95
 
86
96
  it('do clean up on meeting object with LLM disabled', async () => {
@@ -98,6 +108,10 @@ describe('plugin-meetings', () => {
98
108
  assert.calledOnce(meeting.breakouts.cleanUp);
99
109
  assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
100
110
  assert.calledOnce(webex.internal.device.meetingEnded);
111
+ assert.calledOnceWithExactly(
112
+ meeting.webex.internal.newMetrics.callDiagnosticMetrics.clearEventLimitsForCorrelationId,
113
+ meeting.correlationId
114
+ );
101
115
  });
102
116
 
103
117
  it('do clean up on meeting object with no config', async () => {
@@ -114,6 +128,10 @@ describe('plugin-meetings', () => {
114
128
  assert.calledOnce(meeting.breakouts.cleanUp);
115
129
  assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
116
130
  assert.calledOnce(webex.internal.device.meetingEnded);
131
+ assert.calledOnceWithExactly(
132
+ meeting.webex.internal.newMetrics.callDiagnosticMetrics.clearEventLimitsForCorrelationId,
133
+ meeting.correlationId
134
+ );
117
135
  });
118
136
  });
119
137
 
@@ -210,11 +228,11 @@ describe('plugin-meetings', () => {
210
228
  });
211
229
  });
212
230
 
213
- describe('updateLocusWithDelta', () => {
214
- it('should call handleLocusDelta with the new delta locus', () => {
231
+ describe('updateLocusFromApiResponse', () => {
232
+ it('should call handleLocusAPIResponse with the response body', () => {
215
233
  const meeting = {
216
234
  locusInfo: {
217
- handleLocusDelta: sinon.stub(),
235
+ handleLocusAPIResponse: sinon.stub(),
218
236
  },
219
237
  };
220
238
 
@@ -224,16 +242,16 @@ describe('plugin-meetings', () => {
224
242
  },
225
243
  };
226
244
 
227
- const response = MeetingUtil.updateLocusWithDelta(meeting, originalResponse);
245
+ const response = MeetingUtil.updateLocusFromApiResponse(meeting, originalResponse);
228
246
 
229
247
  assert.deepEqual(response, originalResponse);
230
- assert.calledOnceWithExactly(meeting.locusInfo.handleLocusDelta, 'locus', meeting);
248
+ assert.calledOnceWithExactly(meeting.locusInfo.handleLocusAPIResponse, meeting, originalResponse.body);
231
249
  });
232
250
 
233
251
  it('should handle locus being missing from the response', () => {
234
252
  const meeting = {
235
253
  locusInfo: {
236
- handleLocusDelta: sinon.stub(),
254
+ handleLocusAPIResponse: sinon.stub(),
237
255
  },
238
256
  };
239
257
 
@@ -241,10 +259,10 @@ describe('plugin-meetings', () => {
241
259
  body: {},
242
260
  };
243
261
 
244
- const response = MeetingUtil.updateLocusWithDelta(meeting, originalResponse);
262
+ const response = MeetingUtil.updateLocusFromApiResponse(meeting, originalResponse);
245
263
 
246
264
  assert.deepEqual(response, originalResponse);
247
- assert.notCalled(meeting.locusInfo.handleLocusDelta);
265
+ assert.notCalled(meeting.locusInfo.handleLocusAPIResponse);
248
266
  });
249
267
 
250
268
  it('should work with an undefined meeting', () => {
@@ -254,14 +272,14 @@ describe('plugin-meetings', () => {
254
272
  },
255
273
  };
256
274
 
257
- const response = MeetingUtil.updateLocusWithDelta(undefined, originalResponse);
275
+ const response = MeetingUtil.updateLocusFromApiResponse(undefined, originalResponse);
258
276
  assert.deepEqual(response, originalResponse);
259
277
  });
260
278
  });
261
279
 
262
280
  describe('generateLocusDeltaRequest', () => {
263
281
  it('generates the correct wrapper function', async () => {
264
- const updateLocusWithDeltaSpy = sinon.spy(MeetingUtil, 'updateLocusWithDelta');
282
+ const updateLocusFromApiResponseSpy = sinon.spy(MeetingUtil, 'updateLocusFromApiResponse');
265
283
  const addSequenceSpy = sinon.spy(MeetingUtil, 'addSequence');
266
284
 
267
285
  const meeting = {
@@ -278,16 +296,16 @@ describe('plugin-meetings', () => {
278
296
  let result = await locusDeltaRequest(options);
279
297
 
280
298
  assert.equal(result, 'result');
281
- assert.calledOnceWithExactly(updateLocusWithDeltaSpy, meeting, 'result');
299
+ assert.calledOnceWithExactly(updateLocusFromApiResponseSpy, meeting, 'result');
282
300
  assert.calledOnceWithExactly(addSequenceSpy, meeting, options.body);
283
301
 
284
- updateLocusWithDeltaSpy.resetHistory();
302
+ updateLocusFromApiResponseSpy.resetHistory();
285
303
  addSequenceSpy.resetHistory();
286
304
 
287
305
  // body missing from options
288
306
  result = await locusDeltaRequest({});
289
307
  assert.equal(result, 'result');
290
- assert.calledOnceWithExactly(updateLocusWithDeltaSpy, meeting, 'result');
308
+ assert.calledOnceWithExactly(updateLocusFromApiResponseSpy, meeting, 'result');
291
309
  assert.calledOnceWithExactly(addSequenceSpy, meeting, options.body);
292
310
 
293
311
  // meeting disappears so the WeakRef returns undefined
@@ -341,7 +359,11 @@ describe('plugin-meetings', () => {
341
359
  });
342
360
 
343
361
  describe('remoteUpdateAudioVideo', () => {
344
- 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
+ };
345
367
  const meeting = {
346
368
  id: 'meeting-id',
347
369
  mediaId: '12345',
@@ -350,13 +372,14 @@ describe('plugin-meetings', () => {
350
372
  sequence: {},
351
373
  },
352
374
  locusMediaRequest: {
353
- send: sinon.stub().resolves({body: {}, headers: {}}),
375
+ send: sinon.stub().resolves(fakeResponse),
354
376
  },
355
377
  getWebexObject: sinon.stub().returns(webex),
356
378
  };
357
379
 
358
- await MeetingUtil.remoteUpdateAudioVideo(meeting, true, false);
380
+ const result = await MeetingUtil.remoteUpdateAudioVideo(meeting, true, false);
359
381
 
382
+ assert.deepEqual(result, fakeResponse);
360
383
  assert.calledOnceWithExactly(meeting.locusMediaRequest.send, {
361
384
  mediaId: '12345',
362
385
  muteOptions: {
@@ -622,6 +645,28 @@ describe('plugin-meetings', () => {
622
645
 
623
646
  assert.equal(parameter.locusClusterUrl, 'locusClusterUrl');
624
647
  });
648
+
649
+ it('should post client event with error when join fails', async () => {
650
+ const joinError = new Error('Join failed');
651
+ meeting.meetingRequest.joinMeeting.rejects(joinError);
652
+ meeting.meetingInfo = { meetingLookupUrl: 'test-lookup-url' };
653
+
654
+ try {
655
+ await MeetingUtil.joinMeeting(meeting, {});
656
+ assert.fail('Expected joinMeeting to throw an error');
657
+ } catch (error) {
658
+ assert.equal(error, joinError);
659
+
660
+ // Verify error client event was submitted
661
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
662
+ name: 'client.locus.join.response',
663
+ payload: {
664
+ identifiers: { meetingLookupUrl: 'test-lookup-url' },
665
+ },
666
+ options: { meetingId: meeting.id, rawError: joinError },
667
+ });
668
+ }
669
+ });
625
670
  });
626
671
 
627
672
  describe('joinMeetingOptions', () => {
@@ -661,6 +706,82 @@ describe('plugin-meetings', () => {
661
706
  joinMeetingSpy.restore();
662
707
  }
663
708
  });
709
+
710
+ it('should submit client event and reject with PasswordError when password is required', async () => {
711
+ const meeting = {
712
+ id: 'meeting-id',
713
+ passwordStatus: PASSWORD_STATUS.REQUIRED,
714
+ resourceId: null,
715
+ requiredCaptcha: null,
716
+ getWebexObject: sinon.stub().returns(webex),
717
+ };
718
+
719
+ try {
720
+ await MeetingUtil.joinMeetingOptions(meeting, {});
721
+ assert.fail('Expected joinMeetingOptions to throw PasswordError');
722
+ } catch (error) {
723
+ assert.instanceOf(error, PasswordError);
724
+
725
+ // Verify client event was submitted with error details
726
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
727
+ name: 'client.meetinginfo.response',
728
+ options: {
729
+ meetingId: meeting.id,
730
+ },
731
+ payload: {
732
+ errors: [
733
+ {
734
+ fatal: false,
735
+ category: 'expected',
736
+ name: 'other',
737
+ shownToUser: false,
738
+ errorCode: error.code,
739
+ errorDescription: error.name,
740
+ rawErrorMessage: error.sdkMessage,
741
+ },
742
+ ],
743
+ },
744
+ });
745
+ }
746
+ });
747
+
748
+ it('should submit client event and reject with CaptchaError when captcha is required', async () => {
749
+ const meeting = {
750
+ id: 'meeting-id',
751
+ passwordStatus: null,
752
+ resourceId: null,
753
+ requiredCaptcha: {captchaId: 'test-captcha'},
754
+ getWebexObject: sinon.stub().returns(webex),
755
+ };
756
+
757
+ try {
758
+ await MeetingUtil.joinMeetingOptions(meeting, {});
759
+ assert.fail('Expected joinMeetingOptions to throw CaptchaError');
760
+ } catch (error) {
761
+ assert.instanceOf(error, CaptchaError);
762
+
763
+ // Verify client event was submitted with error details
764
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
765
+ name: 'client.meetinginfo.response',
766
+ options: {
767
+ meetingId: meeting.id,
768
+ },
769
+ payload: {
770
+ errors: [
771
+ {
772
+ fatal: false,
773
+ category: 'expected',
774
+ name: 'other',
775
+ shownToUser: false,
776
+ errorCode: error.code,
777
+ errorDescription: error.name,
778
+ rawErrorMessage: error.sdkMessage,
779
+ },
780
+ ],
781
+ },
782
+ });
783
+ }
784
+ });
664
785
  });
665
786
 
666
787
  describe('getUserDisplayHintsFromLocusInfo', () => {
@@ -850,7 +971,15 @@ describe('plugin-meetings', () => {
850
971
  {functionName: 'isClosedCaptionActive', displayHint: 'CAPTION_STATUS_ACTIVE'},
851
972
  {functionName: 'canStartManualCaption', displayHint: 'MANUAL_CAPTION_START'},
852
973
  {functionName: 'canStopManualCaption', displayHint: 'MANUAL_CAPTION_STOP'},
974
+
975
+ {functionName: 'isLocalRecordingStarted',displayHint:'LOCAL_RECORDING_STATUS_STARTED'},
976
+ {functionName: 'isLocalRecordingStopped', displayHint: 'LOCAL_RECORDING_STATUS_STOPPED'},
977
+ {functionName: 'isLocalRecordingPaused', displayHint: 'LOCAL_RECORDING_STATUS_PAUSED'},
978
+
853
979
  {functionName: 'isManualCaptionActive', displayHint: 'MANUAL_CAPTION_STATUS_ACTIVE'},
980
+
981
+ {functionName: 'isSpokenLanguageAutoDetectionEnabled', displayHint: 'SPOKEN_LANGUAGE_AUTO_DETECTION_ENABLED'},
982
+
854
983
  {functionName: 'isWebexAssistantActive', displayHint: 'WEBEX_ASSISTANT_STATUS_ACTIVE'},
855
984
  {functionName: 'canViewCaptionPanel', displayHint: 'ENABLE_CAPTION_PANEL'},
856
985
  {functionName: 'isRealTimeTranslationEnabled', displayHint: 'DISPLAY_REAL_TIME_TRANSLATION'},
@@ -1189,6 +1318,27 @@ describe('plugin-meetings', () => {
1189
1318
  });
1190
1319
  });
1191
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
+
1192
1342
  describe('getChangeMeetingFloorErrorPayload', () => {
1193
1343
  [
1194
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);