@webex/plugin-meetings 3.8.1 → 3.9.0-webinar5k.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 (296) 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 +16 -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/hashTree/constants.js +23 -0
  12. package/dist/hashTree/constants.js.map +1 -0
  13. package/dist/hashTree/hashTree.js +516 -0
  14. package/dist/hashTree/hashTree.js.map +1 -0
  15. package/dist/hashTree/hashTreeParser.js +521 -0
  16. package/dist/hashTree/hashTreeParser.js.map +1 -0
  17. package/dist/interpretation/index.js +1 -1
  18. package/dist/interpretation/siLanguage.js +1 -1
  19. package/dist/locus-info/controlsUtils.js +11 -3
  20. package/dist/locus-info/controlsUtils.js.map +1 -1
  21. package/dist/locus-info/index.js +331 -59
  22. package/dist/locus-info/index.js.map +1 -1
  23. package/dist/media/index.js +2 -2
  24. package/dist/media/index.js.map +1 -1
  25. package/dist/meeting/brbState.js +17 -14
  26. package/dist/meeting/brbState.js.map +1 -1
  27. package/dist/meeting/in-meeting-actions.js +5 -1
  28. package/dist/meeting/in-meeting-actions.js.map +1 -1
  29. package/dist/meeting/index.js +264 -125
  30. package/dist/meeting/index.js.map +1 -1
  31. package/dist/meeting/muteState.js +2 -5
  32. package/dist/meeting/muteState.js.map +1 -1
  33. package/dist/meeting/request.js +19 -0
  34. package/dist/meeting/request.js.map +1 -1
  35. package/dist/meeting/request.type.js.map +1 -1
  36. package/dist/meeting/util.js +8 -11
  37. package/dist/meeting/util.js.map +1 -1
  38. package/dist/meetings/index.js +6 -2
  39. package/dist/meetings/index.js.map +1 -1
  40. package/dist/member/types.js.map +1 -1
  41. package/dist/members/collection.js +13 -0
  42. package/dist/members/collection.js.map +1 -1
  43. package/dist/members/index.js +44 -23
  44. package/dist/members/index.js.map +1 -1
  45. package/dist/members/request.js +3 -3
  46. package/dist/members/request.js.map +1 -1
  47. package/dist/members/util.js +18 -6
  48. package/dist/members/util.js.map +1 -1
  49. package/dist/metrics/constants.js +1 -0
  50. package/dist/metrics/constants.js.map +1 -1
  51. package/dist/multistream/sendSlotManager.js +32 -2
  52. package/dist/multistream/sendSlotManager.js.map +1 -1
  53. package/dist/reachability/index.js +5 -10
  54. package/dist/reachability/index.js.map +1 -1
  55. package/dist/types/constants.d.ts +12 -0
  56. package/dist/types/controls-options-manager/enums.d.ts +2 -1
  57. package/dist/types/controls-options-manager/types.d.ts +4 -1
  58. package/dist/types/hashTree/constants.d.ts +8 -0
  59. package/dist/types/hashTree/hashTree.d.ts +128 -0
  60. package/dist/types/hashTree/hashTreeParser.d.ts +152 -0
  61. package/dist/types/locus-info/index.d.ts +93 -3
  62. package/dist/types/meeting/brbState.d.ts +0 -1
  63. package/dist/types/meeting/in-meeting-actions.d.ts +4 -0
  64. package/dist/types/meeting/index.d.ts +36 -3
  65. package/dist/types/meeting/request.d.ts +9 -1
  66. package/dist/types/meeting/request.type.d.ts +74 -0
  67. package/dist/types/meeting/util.d.ts +3 -3
  68. package/dist/types/member/types.d.ts +1 -0
  69. package/dist/types/members/collection.d.ts +6 -0
  70. package/dist/types/members/index.d.ts +15 -3
  71. package/dist/types/members/request.d.ts +1 -1
  72. package/dist/types/members/util.d.ts +5 -2
  73. package/dist/types/metrics/constants.d.ts +1 -0
  74. package/dist/types/multistream/sendSlotManager.d.ts +16 -0
  75. package/dist/types/reachability/index.d.ts +2 -2
  76. package/dist/webinar/index.js +1 -1
  77. package/package.json +26 -25
  78. package/src/constants.ts +16 -0
  79. package/src/controls-options-manager/enums.ts +1 -0
  80. package/src/controls-options-manager/types.ts +6 -1
  81. package/src/controls-options-manager/util.ts +31 -0
  82. package/src/hashTree/constants.ts +12 -0
  83. package/src/hashTree/hashTree.ts +460 -0
  84. package/src/hashTree/hashTreeParser.ts +556 -0
  85. package/src/locus-info/controlsUtils.ts +15 -0
  86. package/src/locus-info/index.ts +434 -58
  87. package/src/media/index.ts +2 -2
  88. package/src/meeting/brbState.ts +13 -9
  89. package/src/meeting/in-meeting-actions.ts +8 -0
  90. package/src/meeting/index.ts +193 -39
  91. package/src/meeting/muteState.ts +2 -6
  92. package/src/meeting/request.ts +16 -0
  93. package/src/meeting/request.type.ts +64 -0
  94. package/src/meeting/util.ts +17 -20
  95. package/src/meetings/index.ts +17 -3
  96. package/src/member/types.ts +1 -0
  97. package/src/members/collection.ts +11 -0
  98. package/src/members/index.ts +33 -7
  99. package/src/members/request.ts +2 -2
  100. package/src/members/util.ts +14 -3
  101. package/src/metrics/constants.ts +1 -0
  102. package/src/multistream/sendSlotManager.ts +34 -2
  103. package/src/reachability/index.ts +5 -13
  104. package/test/unit/spec/controls-options-manager/util.js +58 -0
  105. package/test/unit/spec/hashTree/hashTree.ts +394 -0
  106. package/test/unit/spec/hashTree/hashTreeParser.ts +156 -0
  107. package/test/unit/spec/locus-info/controlsUtils.js +52 -0
  108. package/test/unit/spec/locus-info/index.js +547 -54
  109. package/test/unit/spec/media/index.ts +107 -0
  110. package/test/unit/spec/meeting/brbState.ts +23 -4
  111. package/test/unit/spec/meeting/in-meeting-actions.ts +4 -0
  112. package/test/unit/spec/meeting/index.js +647 -46
  113. package/test/unit/spec/meeting/request.js +71 -0
  114. package/test/unit/spec/members/index.js +33 -10
  115. package/test/unit/spec/members/request.js +2 -2
  116. package/test/unit/spec/members/utils.js +27 -7
  117. package/test/unit/spec/multistream/sendSlotManager.ts +59 -0
  118. package/test/unit/spec/reachability/index.ts +2 -6
  119. package/dist/annotation/annotation.types.d.ts +0 -42
  120. package/dist/annotation/constants.d.ts +0 -31
  121. package/dist/annotation/index.d.ts +0 -117
  122. package/dist/breakouts/breakout.d.ts +0 -8
  123. package/dist/breakouts/collection.d.ts +0 -5
  124. package/dist/breakouts/edit-lock-error.d.ts +0 -15
  125. package/dist/breakouts/events.d.ts +0 -8
  126. package/dist/breakouts/index.d.ts +0 -5
  127. package/dist/breakouts/request.d.ts +0 -22
  128. package/dist/breakouts/utils.d.ts +0 -15
  129. package/dist/common/browser-detection.d.ts +0 -9
  130. package/dist/common/collection.d.ts +0 -48
  131. package/dist/common/config.d.ts +0 -2
  132. package/dist/common/errors/captcha-error.d.ts +0 -15
  133. package/dist/common/errors/intent-to-join.d.ts +0 -16
  134. package/dist/common/errors/join-meeting.d.ts +0 -17
  135. package/dist/common/errors/media.d.ts +0 -15
  136. package/dist/common/errors/no-meeting-info.d.ts +0 -14
  137. package/dist/common/errors/parameter.d.ts +0 -15
  138. package/dist/common/errors/password-error.d.ts +0 -15
  139. package/dist/common/errors/permission.d.ts +0 -14
  140. package/dist/common/errors/reclaim-host-role-error.d.ts +0 -60
  141. package/dist/common/errors/reclaim-host-role-error.js +0 -158
  142. package/dist/common/errors/reclaim-host-role-error.js.map +0 -1
  143. package/dist/common/errors/reclaim-host-role-errors.d.ts +0 -60
  144. package/dist/common/errors/reconnection-in-progress.d.ts +0 -9
  145. package/dist/common/errors/reconnection-in-progress.js +0 -35
  146. package/dist/common/errors/reconnection-in-progress.js.map +0 -1
  147. package/dist/common/errors/reconnection.d.ts +0 -15
  148. package/dist/common/errors/stats.d.ts +0 -15
  149. package/dist/common/errors/webex-errors.d.ts +0 -81
  150. package/dist/common/errors/webex-meetings-error.d.ts +0 -20
  151. package/dist/common/events/events-scope.d.ts +0 -17
  152. package/dist/common/events/events.d.ts +0 -12
  153. package/dist/common/events/trigger-proxy.d.ts +0 -2
  154. package/dist/common/events/util.d.ts +0 -2
  155. package/dist/common/logs/logger-config.d.ts +0 -2
  156. package/dist/common/logs/logger-proxy.d.ts +0 -2
  157. package/dist/common/logs/request.d.ts +0 -34
  158. package/dist/common/queue.d.ts +0 -32
  159. package/dist/config.d.ts +0 -73
  160. package/dist/constants.d.ts +0 -952
  161. package/dist/controls-options-manager/constants.d.ts +0 -4
  162. package/dist/controls-options-manager/enums.d.ts +0 -5
  163. package/dist/controls-options-manager/index.d.ts +0 -120
  164. package/dist/controls-options-manager/types.d.ts +0 -43
  165. package/dist/controls-options-manager/util.d.ts +0 -7
  166. package/dist/index.d.ts +0 -4
  167. package/dist/interceptors/index.d.ts +0 -2
  168. package/dist/interceptors/locusRetry.d.ts +0 -27
  169. package/dist/interpretation/collection.d.ts +0 -5
  170. package/dist/interpretation/index.d.ts +0 -5
  171. package/dist/interpretation/siLanguage.d.ts +0 -5
  172. package/dist/locus-info/controlsUtils.d.ts +0 -2
  173. package/dist/locus-info/embeddedAppsUtils.d.ts +0 -2
  174. package/dist/locus-info/fullState.d.ts +0 -2
  175. package/dist/locus-info/hostUtils.d.ts +0 -2
  176. package/dist/locus-info/index.d.ts +0 -269
  177. package/dist/locus-info/infoUtils.d.ts +0 -2
  178. package/dist/locus-info/mediaSharesUtils.d.ts +0 -2
  179. package/dist/locus-info/parser.d.ts +0 -212
  180. package/dist/locus-info/selfUtils.d.ts +0 -2
  181. package/dist/media/index.d.ts +0 -32
  182. package/dist/media/properties.d.ts +0 -108
  183. package/dist/media/util.d.ts +0 -2
  184. package/dist/mediaQualityMetrics/config.d.ts +0 -233
  185. package/dist/mediaQualityMetrics/config.js +0 -513
  186. package/dist/mediaQualityMetrics/config.js.map +0 -1
  187. package/dist/meeting/effectsState.d.ts +0 -42
  188. package/dist/meeting/effectsState.js +0 -260
  189. package/dist/meeting/effectsState.js.map +0 -1
  190. package/dist/meeting/in-meeting-actions.d.ts +0 -79
  191. package/dist/meeting/index.d.ts +0 -1622
  192. package/dist/meeting/locusMediaRequest.d.ts +0 -74
  193. package/dist/meeting/muteState.d.ts +0 -116
  194. package/dist/meeting/request.d.ts +0 -257
  195. package/dist/meeting/request.type.d.ts +0 -11
  196. package/dist/meeting/state.d.ts +0 -9
  197. package/dist/meeting/util.d.ts +0 -2
  198. package/dist/meeting/voicea-meeting.d.ts +0 -16
  199. package/dist/meeting-info/collection.d.ts +0 -20
  200. package/dist/meeting-info/index.d.ts +0 -57
  201. package/dist/meeting-info/meeting-info-v2.d.ts +0 -93
  202. package/dist/meeting-info/request.d.ts +0 -22
  203. package/dist/meeting-info/util.d.ts +0 -2
  204. package/dist/meeting-info/utilv2.d.ts +0 -2
  205. package/dist/meetings/collection.d.ts +0 -23
  206. package/dist/meetings/index.d.ts +0 -296
  207. package/dist/meetings/meetings.types.d.ts +0 -4
  208. package/dist/meetings/request.d.ts +0 -27
  209. package/dist/meetings/util.d.ts +0 -18
  210. package/dist/member/index.d.ts +0 -148
  211. package/dist/member/member.types.d.ts +0 -11
  212. package/dist/member/member.types.js +0 -18
  213. package/dist/member/member.types.js.map +0 -1
  214. package/dist/member/types.d.ts +0 -32
  215. package/dist/member/util.d.ts +0 -2
  216. package/dist/members/collection.d.ts +0 -24
  217. package/dist/members/index.d.ts +0 -308
  218. package/dist/members/request.d.ts +0 -58
  219. package/dist/members/types.d.ts +0 -25
  220. package/dist/members/util.d.ts +0 -2
  221. package/dist/metrics/config.d.ts +0 -169
  222. package/dist/metrics/config.js +0 -289
  223. package/dist/metrics/config.js.map +0 -1
  224. package/dist/metrics/constants.d.ts +0 -59
  225. package/dist/metrics/index.d.ts +0 -152
  226. package/dist/multistream/mediaRequestManager.d.ts +0 -119
  227. package/dist/multistream/receiveSlot.d.ts +0 -68
  228. package/dist/multistream/receiveSlotManager.d.ts +0 -56
  229. package/dist/multistream/remoteMedia.d.ts +0 -72
  230. package/dist/multistream/remoteMediaGroup.d.ts +0 -49
  231. package/dist/multistream/remoteMediaManager.d.ts +0 -300
  232. package/dist/multistream/sendSlotManager.d.ts +0 -69
  233. package/dist/networkQualityMonitor/index.d.ts +0 -70
  234. package/dist/networkQualityMonitor/index.js +0 -226
  235. package/dist/networkQualityMonitor/index.js.map +0 -1
  236. package/dist/peer-connection-manager/index.d.ts +0 -6
  237. package/dist/peer-connection-manager/index.js +0 -671
  238. package/dist/peer-connection-manager/index.js.map +0 -1
  239. package/dist/peer-connection-manager/util.d.ts +0 -6
  240. package/dist/peer-connection-manager/util.js +0 -110
  241. package/dist/peer-connection-manager/util.js.map +0 -1
  242. package/dist/personal-meeting-room/index.d.ts +0 -47
  243. package/dist/personal-meeting-room/request.d.ts +0 -14
  244. package/dist/personal-meeting-room/util.d.ts +0 -2
  245. package/dist/reachability/clusterReachability.d.ts +0 -109
  246. package/dist/reachability/index.d.ts +0 -139
  247. package/dist/reachability/request.d.ts +0 -35
  248. package/dist/reachability/util.d.ts +0 -8
  249. package/dist/reactions/constants.d.ts +0 -3
  250. package/dist/reactions/reactions.d.ts +0 -4
  251. package/dist/reactions/reactions.type.d.ts +0 -32
  252. package/dist/reconnection-manager/index.d.ts +0 -112
  253. package/dist/recording-controller/enums.d.ts +0 -7
  254. package/dist/recording-controller/index.d.ts +0 -193
  255. package/dist/recording-controller/util.d.ts +0 -13
  256. package/dist/roap/collection.d.ts +0 -10
  257. package/dist/roap/collection.js +0 -63
  258. package/dist/roap/collection.js.map +0 -1
  259. package/dist/roap/handler.d.ts +0 -47
  260. package/dist/roap/handler.js +0 -279
  261. package/dist/roap/handler.js.map +0 -1
  262. package/dist/roap/index.d.ts +0 -116
  263. package/dist/roap/request.d.ts +0 -35
  264. package/dist/roap/state.d.ts +0 -9
  265. package/dist/roap/state.js +0 -127
  266. package/dist/roap/state.js.map +0 -1
  267. package/dist/roap/turnDiscovery.d.ts +0 -81
  268. package/dist/roap/util.d.ts +0 -2
  269. package/dist/roap/util.js +0 -76
  270. package/dist/roap/util.js.map +0 -1
  271. package/dist/rtcMetrics/constants.d.ts +0 -4
  272. package/dist/rtcMetrics/constants.js +0 -11
  273. package/dist/rtcMetrics/constants.js.map +0 -1
  274. package/dist/rtcMetrics/index.d.ts +0 -61
  275. package/dist/rtcMetrics/index.js +0 -197
  276. package/dist/rtcMetrics/index.js.map +0 -1
  277. package/dist/statsAnalyzer/global.d.ts +0 -118
  278. package/dist/statsAnalyzer/global.js +0 -127
  279. package/dist/statsAnalyzer/global.js.map +0 -1
  280. package/dist/statsAnalyzer/index.d.ts +0 -193
  281. package/dist/statsAnalyzer/index.js +0 -1019
  282. package/dist/statsAnalyzer/index.js.map +0 -1
  283. package/dist/statsAnalyzer/mqaUtil.d.ts +0 -22
  284. package/dist/statsAnalyzer/mqaUtil.js +0 -181
  285. package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
  286. package/dist/transcription/index.d.ts +0 -64
  287. package/dist/types/common/errors/reconnection-in-progress.d.ts +0 -9
  288. package/dist/types/mediaQualityMetrics/config.d.ts +0 -241
  289. package/dist/types/networkQualityMonitor/index.d.ts +0 -70
  290. package/dist/types/rtcMetrics/constants.d.ts +0 -4
  291. package/dist/types/rtcMetrics/index.d.ts +0 -71
  292. package/dist/types/statsAnalyzer/global.d.ts +0 -36
  293. package/dist/types/statsAnalyzer/index.d.ts +0 -217
  294. package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
  295. package/dist/webinar/collection.d.ts +0 -16
  296. package/dist/webinar/index.d.ts +0 -5
@@ -614,20 +614,20 @@ describe('plugin-meetings', () => {
614
614
  assert.calledWith(meeting.members.cancelPhoneInvite, uuid1);
615
615
  });
616
616
  });
617
- describe('#cancelSIPInvite', () => {
618
- it('should have #cancelSIPInvite', () => {
619
- assert.exists(meeting.cancelSIPInvite);
617
+ describe('#cancelInviteByMemberId', () => {
618
+ it('should have #cancelInviteByMemberId', () => {
619
+ assert.exists(meeting.cancelInviteByMemberId);
620
620
  });
621
621
  beforeEach(() => {
622
- meeting.members.cancelSIPInvite = sinon.stub().returns(Promise.resolve(test1));
622
+ meeting.members.cancelInviteByMemberId = sinon.stub().returns(Promise.resolve(test1));
623
623
  });
624
- it('should proxy members #cancelSIPInvite and return a promise', async () => {
625
- const cancel = meeting.cancelSIPInvite({memberId: uuid1});
624
+ it('should proxy members #cancelInviteByMemberId and return a promise', async () => {
625
+ const cancel = meeting.cancelInviteByMemberId({memberId: uuid1});
626
626
 
627
627
  assert.exists(cancel.then);
628
628
  await cancel;
629
- assert.calledOnce(meeting.members.cancelSIPInvite);
630
- assert.calledWith(meeting.members.cancelSIPInvite, {memberId: uuid1});
629
+ assert.calledOnce(meeting.members.cancelInviteByMemberId);
630
+ assert.calledWith(meeting.members.cancelInviteByMemberId, {memberId: uuid1});
631
631
  });
632
632
  });
633
633
  describe('#admit', () => {
@@ -1208,8 +1208,73 @@ describe('plugin-meetings', () => {
1208
1208
  reason: 'joinWithMedia failure',
1209
1209
  });
1210
1210
  });
1211
- });
1212
1211
 
1212
+ it('should ignore sendVideo/receiveVideo when videoEnabled is false', async () => {
1213
+ await meeting.joinWithMedia({
1214
+ joinOptions,
1215
+ mediaOptions: {
1216
+ videoEnabled: false,
1217
+ sendVideo: true,
1218
+ receiveVideo: true,
1219
+ allowMediaInLobby: true,
1220
+ },
1221
+ });
1222
+
1223
+ assert.calledWithMatch(
1224
+ meeting.addMediaInternal,
1225
+ sinon.match.any,
1226
+ sinon.match.any,
1227
+ sinon.match.any,
1228
+ sinon.match.has('videoEnabled', false).and(sinon.match.has('allowMediaInLobby', true))
1229
+ );
1230
+ });
1231
+
1232
+ it('should ignore sendAudio/receiveAudio when audioEnabled is false', async () => {
1233
+ await meeting.joinWithMedia({
1234
+ joinOptions,
1235
+ mediaOptions: {
1236
+ audioEnabled: false,
1237
+ sendAudio: true,
1238
+ receiveAudio: false,
1239
+ allowMediaInLobby: true,
1240
+ },
1241
+ });
1242
+
1243
+ assert.calledWithMatch(
1244
+ meeting.addMediaInternal,
1245
+ sinon.match.any,
1246
+ sinon.match.any,
1247
+ sinon.match.any,
1248
+ sinon.match.has('audioEnabled', false).and(sinon.match.has('allowMediaInLobby', true))
1249
+ );
1250
+ });
1251
+
1252
+ it('should use provided send/receive values when videoEnabled/audioEnabled are true or not set', async () => {
1253
+ await meeting.joinWithMedia({
1254
+ joinOptions,
1255
+ mediaOptions: {
1256
+ sendVideo: true,
1257
+ receiveVideo: false,
1258
+ sendAudio: false,
1259
+ receiveAudio: true,
1260
+ allowMediaInLobby: true,
1261
+ },
1262
+ });
1263
+
1264
+ assert.calledWith(
1265
+ meeting.addMediaInternal,
1266
+ sinon.match.any,
1267
+ sinon.match.any,
1268
+ sinon.match.any,
1269
+ sinon.match({
1270
+ sendVideo: true,
1271
+ receiveVideo: false,
1272
+ sendAudio: false,
1273
+ receiveAudio: true,
1274
+ })
1275
+ );
1276
+ });
1277
+ });
1213
1278
  describe('#isTranscriptionSupported', () => {
1214
1279
  it('should return false if the feature is not supported for the meeting', () => {
1215
1280
  meeting.locusInfo.controls = {transcribe: {caption: false}};
@@ -1223,6 +1288,44 @@ describe('plugin-meetings', () => {
1223
1288
  });
1224
1289
  });
1225
1290
 
1291
+ describe('#update spoken language', () => {
1292
+ beforeEach(() => {
1293
+ webex.internal.voicea.onSpokenLanguageUpdate = sinon.stub();
1294
+ meeting.transcription = {languageOptions: {currentSpokenLanguage: 'en'}};
1295
+ });
1296
+ afterEach(() => {
1297
+ // Restore the original methods after each test
1298
+ sinon.restore();
1299
+ });
1300
+ it('should call voicea.onSpokenLanguageUpdate when joined', async () => {
1301
+ meeting.joinedWith = {state: 'JOINED'};
1302
+ await meeting.locusInfo.emitScoped(
1303
+ {function: 'test', file: 'test'},
1304
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_TRANSCRIPTION_SPOKEN_LANGUAGE_UPDATED,
1305
+ {spokenLanguage: 'fr'}
1306
+ );
1307
+ assert.calledWith(webex.internal.voicea.onSpokenLanguageUpdate, 'fr', meeting.id);
1308
+ assert.equal(meeting.transcription.languageOptions.currentSpokenLanguage, 'fr');
1309
+ assert.calledWith(
1310
+ TriggerProxy.trigger,
1311
+ meeting,
1312
+ {file: 'meeting/index', function: 'setupLocusControlsListener'},
1313
+ EVENT_TRIGGERS.MEETING_TRANSCRIPTION_SPOKEN_LANGUAGE_UPDATED
1314
+ );
1315
+ });
1316
+
1317
+ it('should also call voicea.onSpokenLanguageUpdate when not joined', async () => {
1318
+ meeting.joinedWith = {state: 'NOT_JOINED'};
1319
+ await meeting.locusInfo.emitScoped(
1320
+ {function: 'test', file: 'test'},
1321
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_TRANSCRIPTION_SPOKEN_LANGUAGE_UPDATED,
1322
+ {spokenLanguage: 'de'}
1323
+ );
1324
+ assert.calledWith(webex.internal.voicea.onSpokenLanguageUpdate, 'de');
1325
+ assert.equal(meeting.transcription.languageOptions.currentSpokenLanguage, 'de');
1326
+ });
1327
+ });
1328
+
1226
1329
  describe('#startTranscription', () => {
1227
1330
  beforeEach(() => {
1228
1331
  webex.internal.voicea.on = sinon.stub();
@@ -2061,14 +2164,12 @@ describe('plugin-meetings', () => {
2061
2164
  };
2062
2165
  meeting.mediaProperties.setMediaDirection = sinon.stub().returns(true);
2063
2166
  meeting.mediaProperties.waitForMediaConnectionConnected = sinon.stub().resolves();
2064
- meeting.mediaProperties.getCurrentConnectionInfo = sinon
2065
- .stub()
2066
- .resolves({
2067
- connectionType: 'udp',
2068
- selectedCandidatePairChanges: 2,
2069
- numTransports: 1,
2070
- ipVersion: 'IPv6',
2071
- });
2167
+ meeting.mediaProperties.getCurrentConnectionInfo = sinon.stub().resolves({
2168
+ connectionType: 'udp',
2169
+ selectedCandidatePairChanges: 2,
2170
+ numTransports: 1,
2171
+ ipVersion: 'IPv6',
2172
+ });
2072
2173
  meeting.audio = muteStateStub;
2073
2174
  meeting.video = muteStateStub;
2074
2175
  sinon.stub(Media, 'createMediaConnection').returns(fakeMediaConnection);
@@ -2187,8 +2288,9 @@ describe('plugin-meetings', () => {
2187
2288
  someReachabilityMetric1: 'some value1',
2188
2289
  someReachabilityMetric2: 'some value2',
2189
2290
  selectedCandidatePairChanges: 2,
2190
- isSubnetReachable: null,
2191
- selectedCluster: null,
2291
+ subnet_reachable: null,
2292
+ selected_cluster: null,
2293
+ selected_subnet: null,
2192
2294
  numTransports: 1,
2193
2295
  iceCandidatesCount: 0,
2194
2296
  }
@@ -2235,8 +2337,9 @@ describe('plugin-meetings', () => {
2235
2337
  signalingState: 'unknown',
2236
2338
  connectionState: 'unknown',
2237
2339
  iceConnectionState: 'unknown',
2238
- isSubnetReachable: null,
2239
- selectedCluster: null,
2340
+ subnet_reachable: null,
2341
+ selected_cluster: null,
2342
+ selected_subnet: null,
2240
2343
  })
2241
2344
  );
2242
2345
 
@@ -2302,8 +2405,9 @@ describe('plugin-meetings', () => {
2302
2405
  selectedCandidatePairChanges: 2,
2303
2406
  numTransports: 1,
2304
2407
  iceCandidatesCount: 0,
2305
- isSubnetReachable: null,
2306
- selectedCluster: null,
2408
+ subnet_reachable: null,
2409
+ selected_cluster: null,
2410
+ selected_subnet: null,
2307
2411
  }
2308
2412
  );
2309
2413
  });
@@ -2361,8 +2465,9 @@ describe('plugin-meetings', () => {
2361
2465
  signalingState: 'have-local-offer',
2362
2466
  connectionState: 'connecting',
2363
2467
  iceConnectionState: 'checking',
2364
- isSubnetReachable: null,
2365
- selectedCluster: null,
2468
+ subnet_reachable: null,
2469
+ selected_cluster: null,
2470
+ selected_subnet: null,
2366
2471
  })
2367
2472
  );
2368
2473
 
@@ -2420,8 +2525,9 @@ describe('plugin-meetings', () => {
2420
2525
  signalingState: 'have-local-offer',
2421
2526
  connectionState: 'connecting',
2422
2527
  iceConnectionState: 'checking',
2423
- isSubnetReachable: null,
2424
- selectedCluster: null,
2528
+ subnet_reachable: null,
2529
+ selected_cluster: null,
2530
+ selected_subnet: null,
2425
2531
  })
2426
2532
  );
2427
2533
 
@@ -2943,8 +3049,9 @@ describe('plugin-meetings', () => {
2943
3049
  selectedCandidatePairChanges: 2,
2944
3050
  numTransports: 1,
2945
3051
  iceCandidatesCount: 0,
2946
- isSubnetReachable: null,
2947
- selectedCluster: null,
3052
+ subnet_reachable: null,
3053
+ selected_cluster: null,
3054
+ selected_subnet: null,
2948
3055
  },
2949
3056
  ]);
2950
3057
 
@@ -3151,8 +3258,9 @@ describe('plugin-meetings', () => {
3151
3258
  retriedWithTurnServer: true,
3152
3259
  isJoinWithMediaRetry: false,
3153
3260
  iceCandidatesCount: 0,
3154
- isSubnetReachable: null,
3155
- selectedCluster: null,
3261
+ subnet_reachable: null,
3262
+ selected_cluster: null,
3263
+ selected_subnet: null,
3156
3264
  },
3157
3265
  ]);
3158
3266
  meeting.roap.doTurnDiscovery;
@@ -3286,8 +3394,8 @@ describe('plugin-meetings', () => {
3286
3394
  meeting.mediaConnections = [
3287
3395
  {
3288
3396
  mediaAgentCluster: 'some.cluster',
3289
- }
3290
- ]
3397
+ },
3398
+ ];
3291
3399
  meeting.iceCandidatesCount = 3;
3292
3400
  meeting.iceCandidateErrors.set('701_error', 3);
3293
3401
  meeting.iceCandidateErrors.set('701_turn_host_lookup_received_error', 1);
@@ -3315,8 +3423,9 @@ describe('plugin-meetings', () => {
3315
3423
  iceCandidatesCount: 3,
3316
3424
  '701_error': 3,
3317
3425
  '701_turn_host_lookup_received_error': 1,
3318
- isSubnetReachable: null,
3319
- selectedCluster: 'some.cluster',
3426
+ subnet_reachable: null,
3427
+ selected_cluster: 'some.cluster',
3428
+ selected_subnet: null,
3320
3429
  }
3321
3430
  );
3322
3431
 
@@ -3379,8 +3488,9 @@ describe('plugin-meetings', () => {
3379
3488
  iceConnectionState: 'unknown',
3380
3489
  selectedCandidatePairChanges: 2,
3381
3490
  numTransports: 1,
3382
- isSubnetReachable: null,
3383
- selectedCluster: null,
3491
+ subnet_reachable: null,
3492
+ selected_cluster: null,
3493
+ selected_subnet: null,
3384
3494
  iceCandidatesCount: 0,
3385
3495
  }
3386
3496
  );
@@ -3442,8 +3552,9 @@ describe('plugin-meetings', () => {
3442
3552
  numTransports: 1,
3443
3553
  '701_error': 2,
3444
3554
  '701_turn_host_lookup_received_error': 1,
3445
- isSubnetReachable: null,
3446
- selectedCluster: null,
3555
+ subnet_reachable: null,
3556
+ selected_cluster: null,
3557
+ selected_subnet: null,
3447
3558
  iceCandidatesCount: 0,
3448
3559
  }
3449
3560
  );
@@ -3451,7 +3562,7 @@ describe('plugin-meetings', () => {
3451
3562
  assert.isOk(errorThrown);
3452
3563
  });
3453
3564
 
3454
- it('should send valid isSubnetReachability if media connection success', async () => {
3565
+ it('should send subnet reachablity metrics if media connection success', async () => {
3455
3566
  meeting.roap.doTurnDiscovery = sinon.stub().returns({
3456
3567
  turnServerInfo: undefined,
3457
3568
  turnDiscoverySkippedReason: undefined,
@@ -3465,6 +3576,12 @@ describe('plugin-meetings', () => {
3465
3576
  stopReachability: sinon.stub(),
3466
3577
  isSubnetReachable: sinon.stub().returns(false),
3467
3578
  };
3579
+ meeting.mediaServerIp = '1.2.3.4';
3580
+ meeting.mediaConnections = [
3581
+ {
3582
+ mediaAgentCluster: 'some.cluster',
3583
+ },
3584
+ ];
3468
3585
 
3469
3586
  const forceRtcMetricsSend = sinon.stub().resolves();
3470
3587
  const closeMediaConnectionStub = sinon.stub();
@@ -3492,12 +3609,13 @@ describe('plugin-meetings', () => {
3492
3609
  isJoinWithMediaRetry: false,
3493
3610
  iceCandidatesCount: 0,
3494
3611
  reachability_public_udp_success: 5,
3495
- isSubnetReachable: false,
3496
- selectedCluster: null,
3612
+ subnet_reachable: false,
3613
+ selected_cluster: 'some.cluster',
3614
+ selected_subnet: '1.X.X.X',
3497
3615
  });
3498
3616
  });
3499
3617
 
3500
- it('should send valid isSubnetReachability if media connection fails', async () => {
3618
+ it('should send subnet reachablity metrics if media connection fails', async () => {
3501
3619
  let errorThrown = undefined;
3502
3620
 
3503
3621
  meeting.roap.doTurnDiscovery = sinon.stub().returns({
@@ -3513,6 +3631,12 @@ describe('plugin-meetings', () => {
3513
3631
  stopReachability: sinon.stub(),
3514
3632
  isSubnetReachable: sinon.stub().returns(true),
3515
3633
  };
3634
+ meeting.mediaServerIp = '1.2.3.4';
3635
+ meeting.mediaConnections = [
3636
+ {
3637
+ mediaAgentCluster: 'some.cluster',
3638
+ },
3639
+ ];
3516
3640
 
3517
3641
  const forceRtcMetricsSend = sinon.stub().resolves();
3518
3642
  const closeMediaConnectionStub = sinon.stub();
@@ -3554,8 +3678,9 @@ describe('plugin-meetings', () => {
3554
3678
  selectedCandidatePairChanges: 2,
3555
3679
  numTransports: 1,
3556
3680
  reachability_public_udp_success: 5,
3557
- isSubnetReachable: true,
3558
- selectedCluster: null,
3681
+ subnet_reachable: true,
3682
+ selected_cluster: 'some.cluster',
3683
+ selected_subnet: '1.X.X.X',
3559
3684
  iceCandidatesCount: 0,
3560
3685
  }
3561
3686
  );
@@ -4152,7 +4277,7 @@ describe('plugin-meetings', () => {
4152
4277
  meeting.deviceUrl = 'device url';
4153
4278
  meeting.selfId = 'self id';
4154
4279
  meeting.brbState = createBrbState(meeting, false);
4155
- meeting.brbState.enable = sinon.stub().resolves();
4280
+ sinon.stub(meeting.brbState, 'enable').resolves();
4156
4281
  });
4157
4282
 
4158
4283
  afterEach(() => {
@@ -4216,6 +4341,17 @@ describe('plugin-meetings', () => {
4216
4341
 
4217
4342
  assert.notCalled(meeting.audio.handleServerRemoteMuteUpdate);
4218
4343
  });
4344
+
4345
+ it('should reject when brb enable fails', async () => {
4346
+ meeting.brbState.enable.restore();
4347
+
4348
+ const error = new Error();
4349
+ meeting.meetingRequest.setBrb = sinon.stub().rejects(error);
4350
+
4351
+ await expect(meeting.beRightBack(true)).to.be.rejectedWith(error);
4352
+
4353
+ assert.isFalse(meeting.brbState.state.syncToServerInProgress);
4354
+ });
4219
4355
  });
4220
4356
  });
4221
4357
 
@@ -10011,6 +10147,24 @@ describe('plugin-meetings', () => {
10011
10147
  );
10012
10148
  });
10013
10149
 
10150
+ it('listens to CONTROLS_POLLING_QA_CHANGED', async () => {
10151
+ const state = {example: 'value'};
10152
+
10153
+ await meeting.locusInfo.emitScoped(
10154
+ {function: 'test', file: 'test'},
10155
+ LOCUSINFO.EVENTS.CONTROLS_POLLING_QA_CHANGED,
10156
+ {state}
10157
+ );
10158
+
10159
+ assert.calledWith(
10160
+ TriggerProxy.trigger,
10161
+ meeting,
10162
+ {file: 'meeting/index', function: 'setupLocusControlsListener'},
10163
+ EVENT_TRIGGERS.MEETING_CONTROLS_POLLING_QA_UPDATED,
10164
+ {state}
10165
+ );
10166
+ });
10167
+
10014
10168
  it('listens to the locus interpretation update event', () => {
10015
10169
  const interpretation = {
10016
10170
  siLanguages: [{languageCode: 20, languageName: 'en'}],
@@ -11603,6 +11757,14 @@ describe('plugin-meetings', () => {
11603
11757
  requiredHints: [DISPLAY_HINTS.DISABLE_RDC_MEETING_OPTION],
11604
11758
  displayHints: userDisplayHints,
11605
11759
  });
11760
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
11761
+ requiredHints: [DISPLAY_HINTS.ENABLE_ATTENDEE_START_POLLING_QA],
11762
+ displayHints: userDisplayHints,
11763
+ });
11764
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
11765
+ requiredHints: [DISPLAY_HINTS.DISABLE_ATTENDEE_START_POLLING_QA],
11766
+ displayHints: userDisplayHints,
11767
+ });
11606
11768
 
11607
11769
  assert.calledWith(
11608
11770
  TriggerProxy.trigger,
@@ -13923,4 +14085,443 @@ describe('plugin-meetings', () => {
13923
14085
  assert.equal(result.failureReason, MEETING_INFO_FAILURE_REASON.WRONG_CAPTCHA);
13924
14086
  });
13925
14087
  });
14088
+
14089
+ describe('#setStage', () => {
14090
+ const check = async (options, expectedVideoLayout) => {
14091
+ const locusUrl = `https://locus-test.wbx2.com/locus/api/v1/loci/${uuidv4()}`;
14092
+ meeting.locusUrl = locusUrl;
14093
+
14094
+ const setStagePromise = meeting.setStage(options);
14095
+
14096
+ assert.exists(setStagePromise.then);
14097
+ await setStagePromise;
14098
+
14099
+ assert.calledOnceWithExactly(
14100
+ meeting.meetingRequest.synchronizeStage,
14101
+ locusUrl,
14102
+ expectedVideoLayout
14103
+ );
14104
+ };
14105
+
14106
+ beforeEach(() => {
14107
+ meeting.meetingRequest.synchronizeStage = sinon.stub().returns(Promise.resolve());
14108
+ });
14109
+
14110
+ it('sends the expected request when no options are provided', async () => {
14111
+ await check(undefined, {
14112
+ overrideDefault: true,
14113
+ lockAttendeeViewOnStageOnly: false,
14114
+ stageParameters: {
14115
+ activeSpeakerProportion: 0.5,
14116
+ showActiveSpeaker: {show: false, order: 0},
14117
+ stageManagerType: 0,
14118
+ },
14119
+ });
14120
+ });
14121
+
14122
+ it('sends the expected request when empty options are provided', async () => {
14123
+ await check(
14124
+ {},
14125
+ {
14126
+ overrideDefault: true,
14127
+ lockAttendeeViewOnStageOnly: false,
14128
+ stageParameters: {
14129
+ activeSpeakerProportion: 0.5,
14130
+ showActiveSpeaker: {show: false, order: 0},
14131
+ stageManagerType: 0,
14132
+ },
14133
+ }
14134
+ );
14135
+ });
14136
+
14137
+ [0.25, 0.5, 0.75].forEach((activeSpeakerProportion) => {
14138
+ it(`sends the expected request when only the active speaker proportion option is provided as ${activeSpeakerProportion}`, async () => {
14139
+ await check(
14140
+ {activeSpeakerProportion},
14141
+ {
14142
+ overrideDefault: true,
14143
+ lockAttendeeViewOnStageOnly: false,
14144
+ stageParameters: {
14145
+ activeSpeakerProportion,
14146
+ showActiveSpeaker: {show: false, order: 0},
14147
+ stageManagerType: 0,
14148
+ },
14149
+ }
14150
+ );
14151
+ });
14152
+ });
14153
+
14154
+ it('sends the expected request when only the custom background option is provided', async () => {
14155
+ const customBackground = {
14156
+ url: `https://test.wbx2.com/background/${uuidv4()}.jpg`,
14157
+ };
14158
+
14159
+ await check(
14160
+ {customBackground},
14161
+ {
14162
+ overrideDefault: true,
14163
+ lockAttendeeViewOnStageOnly: false,
14164
+ stageParameters: {
14165
+ activeSpeakerProportion: 0.5,
14166
+ showActiveSpeaker: {show: false, order: 0},
14167
+ stageManagerType: 2,
14168
+ },
14169
+ customLayouts: {background: customBackground},
14170
+ }
14171
+ );
14172
+ });
14173
+
14174
+ it('sends the expected request when only the custom logo option is provided', async () => {
14175
+ const customLogo = {
14176
+ url: `https://test.wbx2.com/logo/${uuidv4()}.png`,
14177
+ position: 'LowerRight',
14178
+ };
14179
+
14180
+ await check(
14181
+ {customLogo},
14182
+ {
14183
+ overrideDefault: true,
14184
+ lockAttendeeViewOnStageOnly: false,
14185
+ stageParameters: {
14186
+ activeSpeakerProportion: 0.5,
14187
+ showActiveSpeaker: {show: false, order: 0},
14188
+ stageManagerType: 1,
14189
+ },
14190
+ customLayouts: {logo: customLogo},
14191
+ }
14192
+ );
14193
+ });
14194
+
14195
+ it('sends the expected request when only the custom name label option is provided', async () => {
14196
+ const customNameLabel = {
14197
+ accentColor: '#0A7806',
14198
+ background: {color: 'rgba(255, 255, 255, 1)'},
14199
+ border: {color: 'rgba(255, 255, 255, 1)'},
14200
+ content: {
14201
+ displayName: {color: 'rgba(0, 0, 0, 0.95)'},
14202
+ subtitle: {color: 'rgba(0, 0, 0, 0.6)'},
14203
+ },
14204
+ decoration: {color: 'rgba(10, 120, 6, 1)'},
14205
+ fadeOut: {delay: 15},
14206
+ type: 'Primary',
14207
+ };
14208
+
14209
+ await check(
14210
+ {customNameLabel},
14211
+ {
14212
+ overrideDefault: true,
14213
+ lockAttendeeViewOnStageOnly: false,
14214
+ stageParameters: {
14215
+ activeSpeakerProportion: 0.5,
14216
+ showActiveSpeaker: {show: false, order: 0},
14217
+ stageManagerType: 4,
14218
+ },
14219
+ nameLabelStyle: customNameLabel,
14220
+ }
14221
+ );
14222
+ });
14223
+
14224
+ it('sends the expected request when only the custom background and logo options are provided', async () => {
14225
+ const customBackground = {
14226
+ url: `https://test.wbx2.com/background/${uuidv4()}.jpg`,
14227
+ };
14228
+ const customLogo = {
14229
+ url: `https://test.wbx2.com/logo/${uuidv4()}.png`,
14230
+ position: 'UpperRight',
14231
+ };
14232
+
14233
+ await check(
14234
+ {customBackground, customLogo},
14235
+ {
14236
+ overrideDefault: true,
14237
+ lockAttendeeViewOnStageOnly: false,
14238
+ stageParameters: {
14239
+ activeSpeakerProportion: 0.5,
14240
+ showActiveSpeaker: {show: false, order: 0},
14241
+ stageManagerType: 3,
14242
+ },
14243
+ customLayouts: {background: customBackground, logo: customLogo},
14244
+ }
14245
+ );
14246
+ });
14247
+
14248
+ it('sends the expected request when only the custom background and name label options are provided', async () => {
14249
+ const customBackground = {
14250
+ url: `https://test.wbx2.com/background/${uuidv4()}.jpg`,
14251
+ };
14252
+ const customNameLabel = {
14253
+ accentColor: '#00A3FF',
14254
+ background: {color: 'rgba(0, 163, 255, 1)'},
14255
+ border: {color: 'rgba(0, 163, 255, 1)'},
14256
+ content: {
14257
+ displayName: {color: 'rgba(255, 255, 255, 0.95)'},
14258
+ subtitle: {color: 'rgba(255, 255, 255, 0.7)'},
14259
+ },
14260
+ decoration: {color: 'rgba(255, 255, 255, 0.95)'},
14261
+ fadeOut: {delay: 15},
14262
+ type: 'PrimaryInverted',
14263
+ };
14264
+
14265
+ await check(
14266
+ {customBackground, customNameLabel},
14267
+ {
14268
+ overrideDefault: true,
14269
+ lockAttendeeViewOnStageOnly: false,
14270
+ stageParameters: {
14271
+ activeSpeakerProportion: 0.5,
14272
+ showActiveSpeaker: {show: false, order: 0},
14273
+ stageManagerType: 6,
14274
+ },
14275
+ customLayouts: {background: customBackground},
14276
+ nameLabelStyle: customNameLabel,
14277
+ }
14278
+ );
14279
+ });
14280
+
14281
+ it('sends the expected request when only the custom logo and name label options are provided', async () => {
14282
+ const customLogo = {
14283
+ url: `https://test.wbx2.com/logo/${uuidv4()}.png`,
14284
+ position: 'UpperLeft',
14285
+ };
14286
+ const customNameLabel = {
14287
+ accentColor: '#942B2B',
14288
+ background: {color: 'rgba(255, 255, 255, 1)'},
14289
+ border: {color: 'rgba(148, 43, 43, 1)'},
14290
+ content: {
14291
+ displayName: {color: 'rgba(0, 0, 0, 0.95)'},
14292
+ subtitle: {color: 'rgba(0, 0, 0, 0.6)'},
14293
+ },
14294
+ decoration: {color: 'rgba(0, 0, 0, 0)'},
14295
+ fadeOut: {delay: 15},
14296
+ type: 'Secondary',
14297
+ };
14298
+
14299
+ await check(
14300
+ {customLogo, customNameLabel},
14301
+ {
14302
+ overrideDefault: true,
14303
+ lockAttendeeViewOnStageOnly: false,
14304
+ stageParameters: {
14305
+ activeSpeakerProportion: 0.5,
14306
+ showActiveSpeaker: {show: false, order: 0},
14307
+ stageManagerType: 5,
14308
+ },
14309
+ customLayouts: {logo: customLogo},
14310
+ nameLabelStyle: customNameLabel,
14311
+ }
14312
+ );
14313
+ });
14314
+
14315
+ it('sends the expected request when only the custom background, logo, name label options are provided', async () => {
14316
+ const customBackground = {
14317
+ url: `https://test.wbx2.com/background/${uuidv4()}.jpg`,
14318
+ };
14319
+ const customLogo = {
14320
+ url: `https://test.wbx2.com/logo/${uuidv4()}.png`,
14321
+ position: 'LowerLeft',
14322
+ };
14323
+ const customNameLabel = {
14324
+ accentColor: '#EBD960',
14325
+ background: {color: 'rgba(235, 217, 96, 0.55)'},
14326
+ border: {color: 'rgba(235, 217, 96, 0.55)'},
14327
+ content: {
14328
+ displayName: {color: 'rgba(255, 255, 255, 0.95)'},
14329
+ subtitle: {color: 'rgba(255, 255, 255, 0.7)'},
14330
+ },
14331
+ decoration: {color: 'rgba(0, 0, 0, 0)'},
14332
+ fadeOut: {delay: 15},
14333
+ type: 'SecondaryInverted',
14334
+ };
14335
+
14336
+ await check(
14337
+ {customBackground, customLogo, customNameLabel},
14338
+ {
14339
+ overrideDefault: true,
14340
+ lockAttendeeViewOnStageOnly: false,
14341
+ stageParameters: {
14342
+ activeSpeakerProportion: 0.5,
14343
+ showActiveSpeaker: {show: false, order: 0},
14344
+ stageManagerType: 7,
14345
+ },
14346
+ customLayouts: {background: customBackground, logo: customLogo},
14347
+ nameLabelStyle: customNameLabel,
14348
+ }
14349
+ );
14350
+ });
14351
+
14352
+ it('sends the expected request when only the important participants option is provided as empty', async () => {
14353
+ await check(
14354
+ {importantParticipants: []},
14355
+ {
14356
+ overrideDefault: true,
14357
+ lockAttendeeViewOnStageOnly: false,
14358
+ stageParameters: {
14359
+ activeSpeakerProportion: 0.5,
14360
+ showActiveSpeaker: {show: false, order: 0},
14361
+ stageManagerType: 0,
14362
+ },
14363
+ }
14364
+ );
14365
+ });
14366
+
14367
+ it('sends the expected request when only the important participants option is provided as populated', async () => {
14368
+ const importantParticipants = [
14369
+ {mainCsi: 11111111, participantId: uuidv4()},
14370
+ {mainCsi: 22222222, participantId: uuidv4()},
14371
+ {mainCsi: 33333333, participantId: uuidv4()},
14372
+ {mainCsi: 44444444, participantId: uuidv4()},
14373
+ {mainCsi: 55555555, participantId: uuidv4()},
14374
+ {mainCsi: 66666666, participantId: uuidv4()},
14375
+ {mainCsi: 77777777, participantId: uuidv4()},
14376
+ {mainCsi: 88888888, participantId: uuidv4()},
14377
+ ];
14378
+
14379
+ await check(
14380
+ {importantParticipants},
14381
+ {
14382
+ overrideDefault: true,
14383
+ lockAttendeeViewOnStageOnly: false,
14384
+ stageParameters: {
14385
+ activeSpeakerProportion: 0.5,
14386
+ importantParticipants: [
14387
+ {...importantParticipants[0], order: 1},
14388
+ {...importantParticipants[1], order: 2},
14389
+ {...importantParticipants[2], order: 3},
14390
+ {...importantParticipants[3], order: 4},
14391
+ {...importantParticipants[4], order: 5},
14392
+ {...importantParticipants[5], order: 6},
14393
+ {...importantParticipants[6], order: 7},
14394
+ {...importantParticipants[7], order: 8},
14395
+ ],
14396
+ showActiveSpeaker: {show: false, order: 0},
14397
+ stageManagerType: 0,
14398
+ },
14399
+ }
14400
+ );
14401
+ });
14402
+
14403
+ [false, true].forEach((lockAttendeeViewOnStage) => {
14404
+ it(`sends the expected request when only the lock attendee view on stage option is provided as ${lockAttendeeViewOnStage}`, async () => {
14405
+ await check(
14406
+ {lockAttendeeViewOnStage},
14407
+ {
14408
+ overrideDefault: true,
14409
+ lockAttendeeViewOnStageOnly: lockAttendeeViewOnStage,
14410
+ stageParameters: {
14411
+ activeSpeakerProportion: 0.5,
14412
+ showActiveSpeaker: {show: false, order: 0},
14413
+ stageManagerType: 0,
14414
+ },
14415
+ }
14416
+ );
14417
+ });
14418
+ });
14419
+
14420
+ [false, true].forEach((showActiveSpeaker) => {
14421
+ it(`sends the expected request when only the show active speaker option is provided as ${showActiveSpeaker}`, async () => {
14422
+ await check(
14423
+ {showActiveSpeaker},
14424
+ {
14425
+ overrideDefault: true,
14426
+ lockAttendeeViewOnStageOnly: false,
14427
+ stageParameters: {
14428
+ activeSpeakerProportion: 0.5,
14429
+ showActiveSpeaker: {show: showActiveSpeaker, order: 0},
14430
+ stageManagerType: 0,
14431
+ },
14432
+ }
14433
+ );
14434
+ });
14435
+ });
14436
+
14437
+ it('sends the expected request when all options are provided', async () => {
14438
+ const activeSpeakerProportion = 0.6;
14439
+ const customBackground = {
14440
+ url: `https://test.wbx2.com/background/${uuidv4()}.jpg`,
14441
+ };
14442
+ const customLogo = {
14443
+ url: `https://test.wbx2.com/logo/${uuidv4()}.png`,
14444
+ position: 'UpperMiddle',
14445
+ };
14446
+ const customNameLabel = {
14447
+ accentColor: '#0A7806',
14448
+ background: {color: 'rgba(255, 255, 255, 1)'},
14449
+ border: {color: 'rgba(255, 255, 255, 1)'},
14450
+ content: {
14451
+ displayName: {color: 'rgba(0, 0, 0, 0.95)'},
14452
+ subtitle: {color: 'rgba(0, 0, 0, 0.6)'},
14453
+ },
14454
+ decoration: {color: 'rgba(10, 120, 6, 1)'},
14455
+ fadeOut: {delay: 15},
14456
+ type: 'Primary',
14457
+ };
14458
+ const importantParticipants = [
14459
+ {mainCsi: 11111111, participantId: uuidv4()},
14460
+ {mainCsi: 22222222, participantId: uuidv4()},
14461
+ {mainCsi: 33333333, participantId: uuidv4()},
14462
+ {mainCsi: 44444444, participantId: uuidv4()},
14463
+ {mainCsi: 55555555, participantId: uuidv4()},
14464
+ {mainCsi: 66666666, participantId: uuidv4()},
14465
+ {mainCsi: 77777777, participantId: uuidv4()},
14466
+ {mainCsi: 88888888, participantId: uuidv4()},
14467
+ ];
14468
+ const lockAttendeeViewOnStage = true;
14469
+ const showActiveSpeaker = true;
14470
+
14471
+ await check(
14472
+ {
14473
+ activeSpeakerProportion,
14474
+ customBackground,
14475
+ customLogo,
14476
+ customNameLabel,
14477
+ importantParticipants,
14478
+ lockAttendeeViewOnStage,
14479
+ showActiveSpeaker,
14480
+ },
14481
+ {
14482
+ overrideDefault: true,
14483
+ lockAttendeeViewOnStageOnly: lockAttendeeViewOnStage,
14484
+ stageParameters: {
14485
+ activeSpeakerProportion,
14486
+ importantParticipants: [
14487
+ {...importantParticipants[0], order: 1},
14488
+ {...importantParticipants[1], order: 2},
14489
+ {...importantParticipants[2], order: 3},
14490
+ {...importantParticipants[3], order: 4},
14491
+ {...importantParticipants[4], order: 5},
14492
+ {...importantParticipants[5], order: 6},
14493
+ {...importantParticipants[6], order: 7},
14494
+ {...importantParticipants[7], order: 8},
14495
+ ],
14496
+ showActiveSpeaker: {show: showActiveSpeaker, order: 0},
14497
+ stageManagerType: 7,
14498
+ },
14499
+ customLayouts: {background: customBackground, logo: customLogo},
14500
+ nameLabelStyle: customNameLabel,
14501
+ }
14502
+ );
14503
+ });
14504
+ });
14505
+
14506
+ describe('#unsetStage', () => {
14507
+ beforeEach(() => {
14508
+ meeting.meetingRequest.synchronizeStage = sinon.stub().returns(Promise.resolve());
14509
+ });
14510
+
14511
+ it('sends the expected request', async () => {
14512
+ const locusUrl = `https://locus-test.wbx2.com/locus/api/v1/loci/${uuidv4()}`;
14513
+ meeting.locusUrl = locusUrl;
14514
+
14515
+ const unsetStagePromise = meeting.unsetStage();
14516
+
14517
+ assert.exists(unsetStagePromise.then);
14518
+ await unsetStagePromise;
14519
+
14520
+ assert.calledOnceWithExactly(
14521
+ meeting.meetingRequest.synchronizeStage,
14522
+ locusUrl,
14523
+ {overrideDefault: false}
14524
+ );
14525
+ });
14526
+ });
13926
14527
  });