@webex/plugin-meetings 3.0.0-beta.3 → 3.0.0-beta.300

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 (601) hide show
  1. package/README.md +46 -8
  2. package/UPGRADING.md +9 -9
  3. package/browsers.js +19 -24
  4. package/dist/annotation/annotation.types.js +7 -0
  5. package/dist/annotation/annotation.types.js.map +1 -0
  6. package/dist/annotation/constants.js +49 -0
  7. package/dist/annotation/constants.js.map +1 -0
  8. package/dist/annotation/index.js +342 -0
  9. package/dist/annotation/index.js.map +1 -0
  10. package/dist/breakouts/breakout.js +216 -0
  11. package/dist/breakouts/breakout.js.map +1 -0
  12. package/dist/breakouts/collection.js +23 -0
  13. package/dist/breakouts/collection.js.map +1 -0
  14. package/dist/breakouts/edit-lock-error.js +52 -0
  15. package/dist/breakouts/edit-lock-error.js.map +1 -0
  16. package/dist/breakouts/events.js +45 -0
  17. package/dist/breakouts/events.js.map +1 -0
  18. package/dist/breakouts/index.js +1048 -0
  19. package/dist/breakouts/index.js.map +1 -0
  20. package/dist/breakouts/request.js +78 -0
  21. package/dist/breakouts/request.js.map +1 -0
  22. package/dist/breakouts/utils.js +67 -0
  23. package/dist/breakouts/utils.js.map +1 -0
  24. package/dist/common/browser-detection.js +1 -20
  25. package/dist/common/browser-detection.js.map +1 -1
  26. package/dist/common/collection.js +5 -20
  27. package/dist/common/collection.js.map +1 -1
  28. package/dist/common/config.js +0 -7
  29. package/dist/common/config.js.map +1 -1
  30. package/dist/common/errors/captcha-error.js +10 -24
  31. package/dist/common/errors/captcha-error.js.map +1 -1
  32. package/dist/common/errors/intent-to-join.js +11 -24
  33. package/dist/common/errors/intent-to-join.js.map +1 -1
  34. package/dist/common/errors/join-meeting.js +12 -25
  35. package/dist/common/errors/join-meeting.js.map +1 -1
  36. package/dist/common/errors/media.js +10 -24
  37. package/dist/common/errors/media.js.map +1 -1
  38. package/dist/common/errors/no-meeting-info.js +51 -0
  39. package/dist/common/errors/no-meeting-info.js.map +1 -0
  40. package/dist/common/errors/parameter.js +5 -33
  41. package/dist/common/errors/parameter.js.map +1 -1
  42. package/dist/common/errors/password-error.js +10 -24
  43. package/dist/common/errors/password-error.js.map +1 -1
  44. package/dist/common/errors/permission.js +9 -23
  45. package/dist/common/errors/permission.js.map +1 -1
  46. package/dist/common/errors/reclaim-host-role-errors.js +158 -0
  47. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  48. package/dist/common/errors/reconnection-in-progress.js +0 -17
  49. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  50. package/dist/common/errors/reconnection.js +10 -24
  51. package/dist/common/errors/reconnection.js.map +1 -1
  52. package/dist/common/errors/stats.js +10 -24
  53. package/dist/common/errors/stats.js.map +1 -1
  54. package/dist/common/errors/webex-errors.js +54 -48
  55. package/dist/common/errors/webex-errors.js.map +1 -1
  56. package/dist/common/errors/webex-meetings-error.js +5 -25
  57. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  58. package/dist/common/events/events-scope.js +0 -22
  59. package/dist/common/events/events-scope.js.map +1 -1
  60. package/dist/common/events/events.js +0 -23
  61. package/dist/common/events/events.js.map +1 -1
  62. package/dist/common/events/trigger-proxy.js +0 -12
  63. package/dist/common/events/trigger-proxy.js.map +1 -1
  64. package/dist/common/events/util.js +0 -15
  65. package/dist/common/events/util.js.map +1 -1
  66. package/dist/common/logs/logger-config.js +0 -4
  67. package/dist/common/logs/logger-config.js.map +1 -1
  68. package/dist/common/logs/logger-proxy.js +1 -8
  69. package/dist/common/logs/logger-proxy.js.map +1 -1
  70. package/dist/common/logs/request.js +41 -60
  71. package/dist/common/logs/request.js.map +1 -1
  72. package/dist/common/queue.js +28 -23
  73. package/dist/common/queue.js.map +1 -1
  74. package/dist/config.js +9 -15
  75. package/dist/config.js.map +1 -1
  76. package/dist/constants.js +315 -68
  77. package/dist/constants.js.map +1 -1
  78. package/dist/controls-options-manager/constants.js +14 -0
  79. package/dist/controls-options-manager/constants.js.map +1 -0
  80. package/dist/controls-options-manager/enums.js +27 -0
  81. package/dist/controls-options-manager/enums.js.map +1 -0
  82. package/dist/controls-options-manager/index.js +297 -0
  83. package/dist/controls-options-manager/index.js.map +1 -0
  84. package/dist/controls-options-manager/types.js +7 -0
  85. package/dist/controls-options-manager/types.js.map +1 -0
  86. package/dist/controls-options-manager/util.js +319 -0
  87. package/dist/controls-options-manager/util.js.map +1 -0
  88. package/dist/index.js +114 -17
  89. package/dist/index.js.map +1 -1
  90. package/dist/interpretation/collection.js +23 -0
  91. package/dist/interpretation/collection.js.map +1 -0
  92. package/dist/interpretation/index.js +366 -0
  93. package/dist/interpretation/index.js.map +1 -0
  94. package/dist/interpretation/siLanguage.js +25 -0
  95. package/dist/interpretation/siLanguage.js.map +1 -0
  96. package/dist/locus-info/controlsUtils.js +101 -29
  97. package/dist/locus-info/controlsUtils.js.map +1 -1
  98. package/dist/locus-info/embeddedAppsUtils.js +3 -26
  99. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  100. package/dist/locus-info/fullState.js +0 -15
  101. package/dist/locus-info/fullState.js.map +1 -1
  102. package/dist/locus-info/hostUtils.js +4 -12
  103. package/dist/locus-info/hostUtils.js.map +1 -1
  104. package/dist/locus-info/index.js +561 -246
  105. package/dist/locus-info/index.js.map +1 -1
  106. package/dist/locus-info/infoUtils.js +10 -38
  107. package/dist/locus-info/infoUtils.js.map +1 -1
  108. package/dist/locus-info/mediaSharesUtils.js +68 -38
  109. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  110. package/dist/locus-info/parser.js +314 -163
  111. package/dist/locus-info/parser.js.map +1 -1
  112. package/dist/locus-info/selfUtils.js +110 -92
  113. package/dist/locus-info/selfUtils.js.map +1 -1
  114. package/dist/media/index.js +103 -231
  115. package/dist/media/index.js.map +1 -1
  116. package/dist/media/properties.js +137 -222
  117. package/dist/media/properties.js.map +1 -1
  118. package/dist/media/util.js +2 -9
  119. package/dist/media/util.js.map +1 -1
  120. package/dist/mediaQualityMetrics/config.js +505 -495
  121. package/dist/mediaQualityMetrics/config.js.map +1 -1
  122. package/dist/meeting/in-meeting-actions.js +93 -14
  123. package/dist/meeting/in-meeting-actions.js.map +1 -1
  124. package/dist/meeting/index.js +4624 -3740
  125. package/dist/meeting/index.js.map +1 -1
  126. package/dist/meeting/locusMediaRequest.js +292 -0
  127. package/dist/meeting/locusMediaRequest.js.map +1 -0
  128. package/dist/meeting/muteState.js +249 -184
  129. package/dist/meeting/muteState.js.map +1 -1
  130. package/dist/meeting/request.js +400 -346
  131. package/dist/meeting/request.js.map +1 -1
  132. package/dist/meeting/request.type.js +7 -0
  133. package/dist/meeting/request.type.js.map +1 -0
  134. package/dist/meeting/state.js +21 -31
  135. package/dist/meeting/state.js.map +1 -1
  136. package/dist/meeting/util.js +598 -586
  137. package/dist/meeting/util.js.map +1 -1
  138. package/dist/meeting-info/collection.js +6 -25
  139. package/dist/meeting-info/collection.js.map +1 -1
  140. package/dist/meeting-info/index.js +87 -39
  141. package/dist/meeting-info/index.js.map +1 -1
  142. package/dist/meeting-info/meeting-info-v2.js +349 -283
  143. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  144. package/dist/meeting-info/request.js +3 -15
  145. package/dist/meeting-info/request.js.map +1 -1
  146. package/dist/meeting-info/util.js +98 -183
  147. package/dist/meeting-info/util.js.map +1 -1
  148. package/dist/meeting-info/utilv2.js +143 -234
  149. package/dist/meeting-info/utilv2.js.map +1 -1
  150. package/dist/meetings/collection.js +26 -19
  151. package/dist/meetings/collection.js.map +1 -1
  152. package/dist/meetings/index.js +813 -596
  153. package/dist/meetings/index.js.map +1 -1
  154. package/dist/meetings/meetings.types.js +7 -0
  155. package/dist/meetings/meetings.types.js.map +1 -0
  156. package/dist/meetings/request.js +26 -41
  157. package/dist/meetings/request.js.map +1 -1
  158. package/dist/meetings/util.js +183 -156
  159. package/dist/meetings/util.js.map +1 -1
  160. package/dist/member/index.js +135 -85
  161. package/dist/member/index.js.map +1 -1
  162. package/dist/member/types.js +25 -0
  163. package/dist/member/types.js.map +1 -0
  164. package/dist/member/util.js +158 -88
  165. package/dist/member/util.js.map +1 -1
  166. package/dist/members/collection.js +13 -12
  167. package/dist/members/collection.js.map +1 -1
  168. package/dist/members/index.js +194 -204
  169. package/dist/members/index.js.map +1 -1
  170. package/dist/members/request.js +113 -68
  171. package/dist/members/request.js.map +1 -1
  172. package/dist/members/types.js +15 -0
  173. package/dist/members/types.js.map +1 -0
  174. package/dist/members/util.js +324 -259
  175. package/dist/members/util.js.map +1 -1
  176. package/dist/metrics/constants.js +14 -7
  177. package/dist/metrics/constants.js.map +1 -1
  178. package/dist/metrics/index.js +11 -558
  179. package/dist/metrics/index.js.map +1 -1
  180. package/dist/multistream/mediaRequestManager.js +263 -50
  181. package/dist/multistream/mediaRequestManager.js.map +1 -1
  182. package/dist/multistream/receiveSlot.js +58 -65
  183. package/dist/multistream/receiveSlot.js.map +1 -1
  184. package/dist/multistream/receiveSlotManager.js +76 -95
  185. package/dist/multistream/receiveSlotManager.js.map +1 -1
  186. package/dist/multistream/remoteMedia.js +62 -76
  187. package/dist/multistream/remoteMedia.js.map +1 -1
  188. package/dist/multistream/remoteMediaGroup.js +66 -43
  189. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  190. package/dist/multistream/remoteMediaManager.js +536 -439
  191. package/dist/multistream/remoteMediaManager.js.map +1 -1
  192. package/dist/multistream/sendSlotManager.js +233 -0
  193. package/dist/multistream/sendSlotManager.js.map +1 -0
  194. package/dist/networkQualityMonitor/index.js +40 -59
  195. package/dist/networkQualityMonitor/index.js.map +1 -1
  196. package/dist/personal-meeting-room/index.js +21 -45
  197. package/dist/personal-meeting-room/index.js.map +1 -1
  198. package/dist/personal-meeting-room/request.js +1 -31
  199. package/dist/personal-meeting-room/request.js.map +1 -1
  200. package/dist/personal-meeting-room/util.js +0 -13
  201. package/dist/personal-meeting-room/util.js.map +1 -1
  202. package/dist/reachability/index.js +322 -200
  203. package/dist/reachability/index.js.map +1 -1
  204. package/dist/reachability/request.js +20 -26
  205. package/dist/reachability/request.js.map +1 -1
  206. package/dist/reactions/constants.js +13 -0
  207. package/dist/reactions/constants.js.map +1 -0
  208. package/dist/reactions/reactions.js +109 -0
  209. package/dist/reactions/reactions.js.map +1 -0
  210. package/dist/reactions/reactions.type.js +36 -0
  211. package/dist/reactions/reactions.type.js.map +1 -0
  212. package/dist/reconnection-manager/index.js +388 -476
  213. package/dist/reconnection-manager/index.js.map +1 -1
  214. package/dist/recording-controller/enums.js +17 -0
  215. package/dist/recording-controller/enums.js.map +1 -0
  216. package/dist/recording-controller/index.js +362 -0
  217. package/dist/recording-controller/index.js.map +1 -0
  218. package/dist/recording-controller/util.js +64 -0
  219. package/dist/recording-controller/util.js.map +1 -0
  220. package/dist/roap/index.js +99 -94
  221. package/dist/roap/index.js.map +1 -1
  222. package/dist/roap/request.js +131 -135
  223. package/dist/roap/request.js.map +1 -1
  224. package/dist/roap/turnDiscovery.js +151 -101
  225. package/dist/roap/turnDiscovery.js.map +1 -1
  226. package/dist/rtcMetrics/constants.js +12 -0
  227. package/dist/rtcMetrics/constants.js.map +1 -0
  228. package/dist/rtcMetrics/index.js +117 -0
  229. package/dist/rtcMetrics/index.js.map +1 -0
  230. package/dist/statsAnalyzer/global.js +1 -95
  231. package/dist/statsAnalyzer/global.js.map +1 -1
  232. package/dist/statsAnalyzer/index.js +416 -497
  233. package/dist/statsAnalyzer/index.js.map +1 -1
  234. package/dist/statsAnalyzer/mqaUtil.js +145 -88
  235. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  236. package/dist/transcription/index.js +22 -47
  237. package/dist/transcription/index.js.map +1 -1
  238. package/dist/types/annotation/annotation.types.d.ts +42 -0
  239. package/dist/types/annotation/constants.d.ts +31 -0
  240. package/dist/types/annotation/index.d.ts +117 -0
  241. package/dist/types/breakouts/breakout.d.ts +8 -0
  242. package/dist/types/breakouts/collection.d.ts +5 -0
  243. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  244. package/dist/types/breakouts/events.d.ts +8 -0
  245. package/dist/types/breakouts/index.d.ts +5 -0
  246. package/dist/types/breakouts/request.d.ts +22 -0
  247. package/dist/types/breakouts/utils.d.ts +15 -0
  248. package/dist/types/common/browser-detection.d.ts +9 -0
  249. package/dist/types/common/collection.d.ts +48 -0
  250. package/dist/types/common/config.d.ts +2 -0
  251. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  252. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  253. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  254. package/dist/types/common/errors/media.d.ts +15 -0
  255. package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
  256. package/dist/types/common/errors/parameter.d.ts +15 -0
  257. package/dist/types/common/errors/password-error.d.ts +15 -0
  258. package/dist/types/common/errors/permission.d.ts +14 -0
  259. package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
  260. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  261. package/dist/types/common/errors/reconnection.d.ts +15 -0
  262. package/dist/types/common/errors/stats.d.ts +15 -0
  263. package/dist/types/common/errors/webex-errors.d.ts +93 -0
  264. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  265. package/dist/types/common/events/events-scope.d.ts +17 -0
  266. package/dist/types/common/events/events.d.ts +12 -0
  267. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  268. package/dist/types/common/events/util.d.ts +2 -0
  269. package/dist/types/common/logs/logger-config.d.ts +2 -0
  270. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  271. package/dist/types/common/logs/request.d.ts +36 -0
  272. package/dist/types/common/queue.d.ts +34 -0
  273. package/dist/types/config.d.ts +71 -0
  274. package/dist/types/constants.d.ts +1066 -0
  275. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  276. package/dist/types/controls-options-manager/enums.d.ts +15 -0
  277. package/dist/types/controls-options-manager/index.d.ts +136 -0
  278. package/dist/types/controls-options-manager/types.d.ts +43 -0
  279. package/dist/types/controls-options-manager/util.d.ts +1 -0
  280. package/dist/types/index.d.ts +7 -0
  281. package/dist/types/interpretation/collection.d.ts +5 -0
  282. package/dist/types/interpretation/index.d.ts +5 -0
  283. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  284. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  285. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  286. package/dist/types/locus-info/fullState.d.ts +2 -0
  287. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  288. package/dist/types/locus-info/index.d.ts +322 -0
  289. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  290. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  291. package/dist/types/locus-info/parser.d.ts +273 -0
  292. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  293. package/dist/types/media/index.d.ts +34 -0
  294. package/dist/types/media/properties.d.ts +93 -0
  295. package/dist/types/media/util.d.ts +2 -0
  296. package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
  297. package/dist/types/meeting/in-meeting-actions.d.ts +163 -0
  298. package/dist/types/meeting/index.d.ts +1676 -0
  299. package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
  300. package/dist/types/meeting/muteState.d.ts +184 -0
  301. package/dist/types/meeting/request.d.ts +290 -0
  302. package/dist/types/meeting/request.type.d.ts +11 -0
  303. package/dist/types/meeting/state.d.ts +9 -0
  304. package/dist/types/meeting/util.d.ts +102 -0
  305. package/dist/types/meeting-info/collection.d.ts +20 -0
  306. package/dist/types/meeting-info/index.d.ts +69 -0
  307. package/dist/types/meeting-info/meeting-info-v2.d.ts +123 -0
  308. package/dist/types/meeting-info/request.d.ts +22 -0
  309. package/dist/types/meeting-info/util.d.ts +2 -0
  310. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  311. package/dist/types/meetings/collection.d.ts +31 -0
  312. package/dist/types/meetings/index.d.ts +367 -0
  313. package/dist/types/meetings/meetings.types.d.ts +4 -0
  314. package/dist/types/meetings/request.d.ts +27 -0
  315. package/dist/types/meetings/util.d.ts +18 -0
  316. package/dist/types/member/index.d.ts +160 -0
  317. package/dist/types/member/types.d.ts +32 -0
  318. package/dist/types/member/util.d.ts +2 -0
  319. package/dist/types/members/collection.d.ts +29 -0
  320. package/dist/types/members/index.d.ts +353 -0
  321. package/dist/types/members/request.d.ts +114 -0
  322. package/dist/types/members/types.d.ts +25 -0
  323. package/dist/types/members/util.d.ts +215 -0
  324. package/dist/types/metrics/constants.d.ts +65 -0
  325. package/dist/types/metrics/index.d.ts +45 -0
  326. package/dist/types/multistream/mediaRequestManager.d.ts +118 -0
  327. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  328. package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
  329. package/dist/types/multistream/remoteMedia.d.ts +72 -0
  330. package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
  331. package/dist/types/multistream/remoteMediaManager.d.ts +285 -0
  332. package/dist/types/multistream/sendSlotManager.d.ts +61 -0
  333. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  334. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  335. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  336. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  337. package/dist/types/reachability/index.d.ts +194 -0
  338. package/dist/types/reachability/request.d.ts +39 -0
  339. package/dist/types/reactions/constants.d.ts +3 -0
  340. package/dist/types/reactions/reactions.d.ts +4 -0
  341. package/dist/types/reactions/reactions.type.d.ts +52 -0
  342. package/dist/types/reconnection-manager/index.d.ts +126 -0
  343. package/dist/types/recording-controller/enums.d.ts +7 -0
  344. package/dist/types/recording-controller/index.d.ts +207 -0
  345. package/dist/types/recording-controller/util.d.ts +14 -0
  346. package/dist/types/roap/index.d.ts +78 -0
  347. package/dist/types/roap/request.d.ts +39 -0
  348. package/dist/types/roap/turnDiscovery.d.ts +92 -0
  349. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  350. package/dist/types/rtcMetrics/index.d.ts +47 -0
  351. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  352. package/dist/types/statsAnalyzer/index.d.ts +201 -0
  353. package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
  354. package/dist/types/transcription/index.d.ts +64 -0
  355. package/dist/types/webinar/collection.d.ts +16 -0
  356. package/dist/types/webinar/index.d.ts +5 -0
  357. package/dist/webinar/collection.js +44 -0
  358. package/dist/webinar/collection.js.map +1 -0
  359. package/dist/webinar/index.js +69 -0
  360. package/dist/webinar/index.js.map +1 -0
  361. package/internal-README.md +7 -6
  362. package/package.json +29 -21
  363. package/src/annotation/annotation.types.ts +50 -0
  364. package/src/annotation/constants.ts +36 -0
  365. package/src/annotation/index.ts +328 -0
  366. package/src/breakouts/README.md +220 -0
  367. package/src/breakouts/breakout.ts +188 -0
  368. package/src/breakouts/collection.ts +19 -0
  369. package/src/breakouts/edit-lock-error.ts +25 -0
  370. package/src/breakouts/events.ts +56 -0
  371. package/src/breakouts/index.ts +925 -0
  372. package/src/breakouts/request.ts +55 -0
  373. package/src/breakouts/utils.ts +57 -0
  374. package/src/common/{browser-detection.js → browser-detection.ts} +9 -6
  375. package/src/common/collection.ts +9 -7
  376. package/src/common/{config.js → config.ts} +1 -1
  377. package/src/common/errors/{captcha-error.js → captcha-error.ts} +11 -7
  378. package/src/common/errors/{intent-to-join.js → intent-to-join.ts} +12 -7
  379. package/src/common/errors/{join-meeting.js → join-meeting.ts} +17 -8
  380. package/src/common/errors/{media.js → media.ts} +11 -7
  381. package/src/common/errors/no-meeting-info.ts +24 -0
  382. package/src/common/errors/parameter.ts +11 -7
  383. package/src/common/errors/{password-error.js → password-error.ts} +11 -7
  384. package/src/common/errors/{permission.js → permission.ts} +10 -6
  385. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  386. package/src/common/errors/{reconnection.js → reconnection.ts} +11 -7
  387. package/src/common/errors/{stats.js → stats.ts} +11 -7
  388. package/src/common/errors/{webex-errors.js → webex-errors.ts} +51 -8
  389. package/src/common/errors/{webex-meetings-error.js → webex-meetings-error.ts} +4 -2
  390. package/src/common/events/{events-scope.js → events-scope.ts} +6 -2
  391. package/src/common/events/{events.js → events.ts} +5 -1
  392. package/src/common/events/{trigger-proxy.js → trigger-proxy.ts} +9 -5
  393. package/src/common/events/{util.js → util.ts} +2 -3
  394. package/src/common/logs/{logger-config.js → logger-config.ts} +1 -2
  395. package/src/common/logs/logger-proxy.ts +44 -0
  396. package/src/common/logs/{request.js → request.ts} +26 -9
  397. package/src/common/queue.ts +22 -9
  398. package/src/{config.js → config.ts} +18 -19
  399. package/src/constants.ts +260 -22
  400. package/src/controls-options-manager/constants.ts +5 -0
  401. package/src/controls-options-manager/enums.ts +18 -0
  402. package/src/controls-options-manager/index.ts +278 -0
  403. package/src/controls-options-manager/types.ts +59 -0
  404. package/src/controls-options-manager/util.ts +300 -0
  405. package/src/index.ts +40 -0
  406. package/src/interpretation/README.md +60 -0
  407. package/src/interpretation/collection.ts +19 -0
  408. package/src/interpretation/index.ts +332 -0
  409. package/src/interpretation/siLanguage.ts +18 -0
  410. package/src/locus-info/controlsUtils.ts +222 -0
  411. package/src/locus-info/{embeddedAppsUtils.js → embeddedAppsUtils.ts} +5 -6
  412. package/src/locus-info/{fullState.js → fullState.ts} +16 -12
  413. package/src/locus-info/{hostUtils.js → hostUtils.ts} +9 -8
  414. package/src/locus-info/{index.js → index.ts} +557 -119
  415. package/src/locus-info/{infoUtils.js → infoUtils.ts} +29 -10
  416. package/src/locus-info/{mediaSharesUtils.js → mediaSharesUtils.ts} +81 -17
  417. package/src/locus-info/{parser.js → parser.ts} +303 -104
  418. package/src/locus-info/{selfUtils.js → selfUtils.ts} +199 -68
  419. package/src/media/index.ts +458 -0
  420. package/src/media/properties.ts +283 -0
  421. package/src/media/{util.js → util.ts} +2 -2
  422. package/src/mediaQualityMetrics/config.ts +384 -0
  423. package/src/meeting/in-meeting-actions.ts +191 -3
  424. package/src/meeting/index.ts +7882 -0
  425. package/src/meeting/locusMediaRequest.ts +313 -0
  426. package/src/meeting/muteState.ts +451 -0
  427. package/src/meeting/{request.js → request.ts} +421 -220
  428. package/src/meeting/request.type.ts +13 -0
  429. package/src/meeting/{state.js → state.ts} +50 -35
  430. package/src/meeting/util.ts +697 -0
  431. package/src/meeting-info/{collection.js → collection.ts} +6 -2
  432. package/src/meeting-info/index.ts +210 -0
  433. package/src/meeting-info/meeting-info-v2.ts +429 -0
  434. package/src/meeting-info/{request.js → request.ts} +14 -4
  435. package/src/meeting-info/{util.js → util.ts} +60 -51
  436. package/src/meeting-info/{utilv2.js → utilv2.ts} +78 -71
  437. package/src/meetings/{collection.js → collection.ts} +26 -3
  438. package/src/meetings/index.ts +1470 -0
  439. package/src/meetings/meetings.types.ts +12 -0
  440. package/src/meetings/{request.js → request.ts} +34 -25
  441. package/src/meetings/{util.js → util.ts} +132 -37
  442. package/src/member/{index.js → index.ts} +160 -56
  443. package/src/member/types.ts +38 -0
  444. package/src/member/util.ts +397 -0
  445. package/src/members/{collection.js → collection.ts} +10 -2
  446. package/src/members/{index.js → index.ts} +351 -146
  447. package/src/members/request.ts +255 -0
  448. package/src/members/types.ts +29 -0
  449. package/src/members/util.ts +353 -0
  450. package/src/metrics/{constants.js → constants.ts} +12 -6
  451. package/src/metrics/index.ts +73 -0
  452. package/src/multistream/mediaRequestManager.ts +337 -63
  453. package/src/multistream/receiveSlot.ts +69 -26
  454. package/src/multistream/receiveSlotManager.ts +66 -42
  455. package/src/multistream/remoteMedia.ts +40 -5
  456. package/src/multistream/remoteMediaGroup.ts +63 -3
  457. package/src/multistream/remoteMediaManager.ts +300 -66
  458. package/src/multistream/sendSlotManager.ts +170 -0
  459. package/src/networkQualityMonitor/{index.js → index.ts} +41 -29
  460. package/src/personal-meeting-room/{index.js → index.ts} +28 -19
  461. package/src/personal-meeting-room/{request.js → request.ts} +13 -4
  462. package/src/personal-meeting-room/{util.js → util.ts} +4 -4
  463. package/src/reachability/index.ts +671 -0
  464. package/src/reachability/request.ts +50 -35
  465. package/src/reactions/constants.ts +4 -0
  466. package/src/reactions/reactions.ts +104 -0
  467. package/src/reactions/reactions.type.ts +62 -0
  468. package/src/reconnection-manager/{index.js → index.ts} +258 -138
  469. package/src/recording-controller/enums.ts +8 -0
  470. package/src/recording-controller/index.ts +332 -0
  471. package/src/recording-controller/util.ts +75 -0
  472. package/src/roap/{index.js → index.ts} +127 -79
  473. package/src/roap/request.ts +153 -0
  474. package/src/roap/turnDiscovery.ts +109 -47
  475. package/src/rtcMetrics/constants.ts +3 -0
  476. package/src/rtcMetrics/index.ts +100 -0
  477. package/src/statsAnalyzer/global.ts +37 -0
  478. package/src/statsAnalyzer/index.ts +1250 -0
  479. package/src/statsAnalyzer/mqaUtil.ts +292 -0
  480. package/src/transcription/{index.js → index.ts} +46 -39
  481. package/src/webinar/collection.ts +31 -0
  482. package/src/webinar/index.ts +62 -0
  483. package/test/integration/spec/converged-space-meetings.js +233 -0
  484. package/test/integration/spec/journey.js +790 -530
  485. package/test/integration/spec/space-meeting.js +391 -204
  486. package/test/integration/spec/transcription.js +7 -8
  487. package/test/unit/spec/annotation/index.ts +418 -0
  488. package/test/unit/spec/breakouts/breakout.ts +237 -0
  489. package/test/unit/spec/breakouts/collection.ts +15 -0
  490. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  491. package/test/unit/spec/breakouts/events.ts +89 -0
  492. package/test/unit/spec/breakouts/index.ts +1790 -0
  493. package/test/unit/spec/breakouts/request.ts +104 -0
  494. package/test/unit/spec/breakouts/utils.js +72 -0
  495. package/test/unit/spec/common/browser-detection.js +9 -28
  496. package/test/unit/spec/common/queue.js +31 -2
  497. package/test/unit/spec/controls-options-manager/index.js +287 -0
  498. package/test/unit/spec/controls-options-manager/util.js +582 -0
  499. package/test/unit/spec/fixture/locus.js +93 -90
  500. package/test/unit/spec/interpretation/collection.ts +15 -0
  501. package/test/unit/spec/interpretation/index.ts +589 -0
  502. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  503. package/test/unit/spec/locus-info/controlsUtils.js +325 -32
  504. package/test/unit/spec/locus-info/embeddedAppsUtils.js +8 -6
  505. package/test/unit/spec/locus-info/index.js +1390 -17
  506. package/test/unit/spec/locus-info/infoUtils.js +71 -40
  507. package/test/unit/spec/locus-info/lib/BasicSeqCmp.json +88 -430
  508. package/test/unit/spec/locus-info/lib/SeqCmp.json +529 -685
  509. package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
  510. package/test/unit/spec/locus-info/parser.js +119 -44
  511. package/test/unit/spec/locus-info/selfConstant.js +120 -103
  512. package/test/unit/spec/locus-info/selfUtils.js +296 -12
  513. package/test/unit/spec/media/index.ts +128 -77
  514. package/test/unit/spec/media/properties.ts +11 -11
  515. package/test/unit/spec/meeting/in-meeting-actions.ts +92 -3
  516. package/test/unit/spec/meeting/index.js +7433 -2752
  517. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  518. package/test/unit/spec/meeting/muteState.js +420 -211
  519. package/test/unit/spec/meeting/request.js +545 -79
  520. package/test/unit/spec/meeting/utils.js +722 -174
  521. package/test/unit/spec/meeting-info/index.js +300 -0
  522. package/test/unit/spec/meeting-info/meetinginfov2.js +624 -76
  523. package/test/unit/spec/meeting-info/request.js +7 -9
  524. package/test/unit/spec/meeting-info/util.js +11 -12
  525. package/test/unit/spec/meeting-info/utilv2.js +131 -74
  526. package/test/unit/spec/meetings/collection.js +15 -1
  527. package/test/unit/spec/meetings/index.js +1365 -377
  528. package/test/unit/spec/meetings/utils.js +216 -14
  529. package/test/unit/spec/member/index.js +61 -7
  530. package/test/unit/spec/member/util.js +526 -26
  531. package/test/unit/spec/members/index.js +536 -55
  532. package/test/unit/spec/members/request.js +228 -40
  533. package/test/unit/spec/members/utils.js +217 -4
  534. package/test/unit/spec/metrics/index.js +12 -66
  535. package/test/unit/spec/multistream/mediaRequestManager.ts +1012 -109
  536. package/test/unit/spec/multistream/receiveSlot.ts +77 -18
  537. package/test/unit/spec/multistream/receiveSlotManager.ts +69 -39
  538. package/test/unit/spec/multistream/remoteMedia.ts +40 -2
  539. package/test/unit/spec/multistream/remoteMediaGroup.ts +271 -5
  540. package/test/unit/spec/multistream/remoteMediaManager.ts +738 -65
  541. package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
  542. package/test/unit/spec/networkQualityMonitor/index.js +24 -18
  543. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -7
  544. package/test/unit/spec/reachability/index.ts +598 -26
  545. package/test/unit/spec/reachability/request.js +68 -0
  546. package/test/unit/spec/reconnection-manager/index.js +181 -12
  547. package/test/unit/spec/recording-controller/index.js +307 -0
  548. package/test/unit/spec/recording-controller/util.js +229 -0
  549. package/test/unit/spec/roap/index.ts +179 -64
  550. package/test/unit/spec/roap/request.ts +232 -0
  551. package/test/unit/spec/roap/turnDiscovery.ts +123 -58
  552. package/test/unit/spec/rtcMetrics/index.ts +73 -0
  553. package/test/unit/spec/stats-analyzer/index.js +199 -60
  554. package/test/unit/spec/webinar/collection.ts +13 -0
  555. package/test/unit/spec/webinar/index.ts +60 -0
  556. package/test/utils/cmr.js +44 -42
  557. package/test/utils/constants.js +9 -0
  558. package/test/utils/integrationTestUtils.js +46 -0
  559. package/test/utils/testUtils.js +63 -99
  560. package/test/utils/webex-config.js +22 -18
  561. package/test/utils/webex-test-users.js +57 -50
  562. package/tsconfig.json +6 -0
  563. package/dist/media/internal-media-core-wrapper.js +0 -22
  564. package/dist/media/internal-media-core-wrapper.js.map +0 -1
  565. package/dist/meeting/effectsState.js +0 -327
  566. package/dist/meeting/effectsState.js.map +0 -1
  567. package/dist/metrics/config.js +0 -301
  568. package/dist/metrics/config.js.map +0 -1
  569. package/dist/multistream/multistreamMedia.js +0 -116
  570. package/dist/multistream/multistreamMedia.js.map +0 -1
  571. package/dist/peer-connection-manager/util.js +0 -124
  572. package/dist/peer-connection-manager/util.js.map +0 -1
  573. package/src/common/logs/logger-proxy.js +0 -33
  574. package/src/index.js +0 -15
  575. package/src/locus-info/controlsUtils.js +0 -102
  576. package/src/media/index.js +0 -459
  577. package/src/media/internal-media-core-wrapper.ts +0 -9
  578. package/src/media/properties.js +0 -289
  579. package/src/mediaQualityMetrics/config.js +0 -382
  580. package/src/meeting/effectsState.js +0 -205
  581. package/src/meeting/index.js +0 -6284
  582. package/src/meeting/muteState.js +0 -318
  583. package/src/meeting/util.js +0 -506
  584. package/src/meeting-info/index.js +0 -131
  585. package/src/meeting-info/meeting-info-v2.js +0 -255
  586. package/src/meetings/index.js +0 -1015
  587. package/src/member/util.js +0 -254
  588. package/src/members/request.js +0 -131
  589. package/src/members/util.js +0 -258
  590. package/src/metrics/config.js +0 -324
  591. package/src/metrics/index.js +0 -530
  592. package/src/multistream/multistreamMedia.ts +0 -92
  593. package/src/peer-connection-manager/util.ts +0 -117
  594. package/src/reachability/index.js +0 -464
  595. package/src/roap/request.js +0 -127
  596. package/src/statsAnalyzer/global.js +0 -133
  597. package/src/statsAnalyzer/index.js +0 -1006
  598. package/src/statsAnalyzer/mqaUtil.js +0 -173
  599. package/test/unit/spec/meeting/effectsState.js +0 -291
  600. package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -389
  601. /package/src/common/errors/{reconnection-in-progress.js → reconnection-in-progress.ts} +0 -0
@@ -1,78 +1,84 @@
1
1
  import sinon from 'sinon';
2
2
  import {assert} from '@webex/test-helper-chai';
3
+ import Meetings from '@webex/plugin-meetings';
3
4
  import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
4
5
  import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
5
- import LoggerConfig
6
- from '@webex/plugin-meetings/src/common/logs/logger-config';
7
- import Metrics from '@webex/plugin-meetings/src/metrics/index';
8
-
6
+ import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
7
+ import {SELF_POLICY, IP_VERSION} from '@webex/plugin-meetings/src/constants';
8
+ import MockWebex from '@webex/test-helper-mock-webex';
9
+ import * as BrowserDetectionModule from '@webex/plugin-meetings/src/common/browser-detection';
9
10
 
10
11
  describe('plugin-meetings', () => {
12
+ let webex;
11
13
  describe('Meeting utils function', () => {
12
14
  const sandbox = sinon.createSandbox();
13
15
  const meeting = {};
14
16
 
15
17
  beforeEach(() => {
16
- Metrics.postEvent = sinon.stub();
18
+ webex = new MockWebex({
19
+ children: {
20
+ meetings: Meetings,
21
+ },
22
+ });
17
23
  const logger = {
18
24
  info: sandbox.stub(),
19
25
  log: sandbox.stub(),
20
26
  error: sandbox.stub(),
21
- warn: sandbox.stub()
27
+ warn: sandbox.stub(),
28
+ debug: sandbox.stub(),
22
29
  };
23
30
 
24
31
  LoggerConfig.set({
25
32
  verboseEvents: true,
26
- enable: true
33
+ enable: true,
27
34
  });
28
35
  LoggerProxy.set(logger);
29
36
 
30
- meeting.closeLocalStream = sinon.stub()
31
- .returns(Promise.resolve());
32
- meeting.closeLocalShare = sinon.stub()
33
- .returns(Promise.resolve());
34
- meeting.closeRemoteTracks = sinon.stub()
35
- .returns(Promise.resolve());
36
- meeting.closePeerConnections = sinon.stub()
37
- .returns(Promise.resolve());
38
-
39
- meeting.unsetLocalVideoTrack = sinon.stub();
40
- meeting.unsetLocalShareTrack = sinon.stub();
41
- meeting.unsetRemoteTracks = sinon.stub();
37
+ meeting.cleanupLocalStreams = sinon.stub().returns(Promise.resolve());
38
+ meeting.closeRemoteStreams = sinon.stub().returns(Promise.resolve());
39
+ meeting.closePeerConnections = sinon.stub().returns(Promise.resolve());
40
+
41
+ meeting.unsetRemoteStreams = sinon.stub();
42
42
  meeting.unsetPeerConnections = sinon.stub();
43
43
  meeting.reconnectionManager = {cleanUp: sinon.stub()};
44
44
  meeting.stopKeepAlive = sinon.stub();
45
+ meeting.updateLLMConnection = sinon.stub();
46
+ meeting.breakouts = {cleanUp: sinon.stub()};
47
+ meeting.annotaion = {cleanUp: sinon.stub()};
48
+ meeting.getWebexObject = sinon.stub().returns(webex);
49
+ meeting.simultaneousInterpretation = {cleanUp: sinon.stub()};
50
+ meeting.trigger = sinon.stub();
45
51
  });
46
52
 
47
53
  afterEach(() => {
48
54
  sandbox.restore();
55
+ sinon.restore();
49
56
  });
50
57
 
51
58
  describe('#cleanup', () => {
52
59
  it('do clean up on meeting object', async () => {
53
60
  await MeetingUtil.cleanUp(meeting);
54
- assert.calledOnce(meeting.closeLocalStream);
55
- assert.calledOnce(meeting.closeLocalStream);
56
- assert.calledOnce(meeting.closeLocalShare);
57
- assert.calledOnce(meeting.closeRemoteTracks);
61
+ assert.calledOnce(meeting.cleanupLocalStreams);
62
+ assert.calledOnce(meeting.closeRemoteStreams);
58
63
  assert.calledOnce(meeting.closePeerConnections);
59
64
 
60
- assert.calledOnce(meeting.unsetLocalVideoTrack);
61
- assert.calledOnce(meeting.unsetLocalShareTrack);
62
- assert.calledOnce(meeting.unsetRemoteTracks);
65
+ assert.calledOnce(meeting.unsetRemoteStreams);
63
66
  assert.calledOnce(meeting.unsetPeerConnections);
64
67
  assert.calledOnce(meeting.reconnectionManager.cleanUp);
65
68
  assert.calledOnce(meeting.stopKeepAlive);
69
+ assert.calledOnce(meeting.updateLLMConnection);
70
+ assert.calledOnce(meeting.breakouts.cleanUp);
71
+ assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
66
72
  });
67
73
  });
68
74
 
69
75
  describe('logging', () => {
70
76
  const fakeDevice = sinon.fake.returns({
71
- deviceId: 'device-1'
77
+ deviceId: 'device-1',
72
78
  });
73
79
 
74
- const mockTrack = {
75
- getSettings: fakeDevice
80
+ const mockStream = {
81
+ getSettings: fakeDevice,
76
82
  };
77
83
 
78
84
  it('#log - should log [info, warn, error, log] to console', () => {
@@ -90,27 +96,27 @@ describe('plugin-meetings', () => {
90
96
  });
91
97
 
92
98
  describe('#handleAudioLogging', () => {
93
- it('should not log if called without track', () => {
99
+ it('should not log if called without stream', () => {
94
100
  MeetingUtil.handleAudioLogging();
95
101
  assert(!LoggerProxy.logger.log.called, 'log not called');
96
102
  });
97
103
 
98
- it('should log audioTrack settings', () => {
104
+ it('should log audioStream settings', () => {
99
105
  assert(MeetingUtil.handleAudioLogging, 'method is defined');
100
- MeetingUtil.handleAudioLogging(mockTrack);
106
+ MeetingUtil.handleAudioLogging(mockStream);
101
107
  assert(LoggerProxy.logger.log.called, 'log called');
102
108
  });
103
109
  });
104
110
 
105
111
  describe('#handleVideoLogging', () => {
106
- it('should not log if called without track', () => {
112
+ it('should not log if called without stream', () => {
107
113
  MeetingUtil.handleVideoLogging(null);
108
114
  assert(!LoggerProxy.logger.log.called, 'log not called');
109
115
  });
110
116
 
111
- it('should log videoTrack settings', () => {
117
+ it('should log videoStream settings', () => {
112
118
  assert(MeetingUtil.handleVideoLogging, 'method is defined');
113
- MeetingUtil.handleVideoLogging(mockTrack);
119
+ MeetingUtil.handleVideoLogging(mockStream);
114
120
  assert(LoggerProxy.logger.log.called, 'log called');
115
121
  });
116
122
  });
@@ -122,10 +128,7 @@ describe('plugin-meetings', () => {
122
128
  });
123
129
 
124
130
  it('should log device settings', () => {
125
- const mockDevices = [
126
- {deviceId: 'device-1'},
127
- {deviceId: 'device-2'}
128
- ];
131
+ const mockDevices = [{deviceId: 'device-1'}, {deviceId: 'device-2'}];
129
132
 
130
133
  assert(MeetingUtil.handleDeviceLogging, 'is defined');
131
134
  MeetingUtil.handleDeviceLogging(mockDevices);
@@ -134,51 +137,236 @@ describe('plugin-meetings', () => {
134
137
  });
135
138
  });
136
139
 
137
- describe('remoteUpdateAudioVideo', () => {
138
- it('#Should call meetingRequest.remoteAudioVideoToggle with correct parameters (multistream)', async () => {
140
+ describe('addSequence', () => {
141
+ it('should add the sequence object to a request body', () => {
142
+ const body = {};
143
+
144
+ MeetingUtil.addSequence(
145
+ {
146
+ locusInfo: {
147
+ sequence: 'sequence',
148
+ },
149
+ },
150
+ body
151
+ );
152
+
153
+ assert.deepEqual(body, {
154
+ sequence: 'sequence',
155
+ });
156
+ });
157
+
158
+ it('should work with an undefined meeting', () => {
159
+ const body = {};
160
+
161
+ MeetingUtil.addSequence(undefined, body);
162
+
163
+ assert.deepEqual(body, {});
164
+ });
165
+
166
+ it('should work with an undefined locusInfo', () => {
167
+ const body = {};
168
+
169
+ MeetingUtil.addSequence({}, body);
170
+
171
+ assert.deepEqual(body, {});
172
+ });
173
+
174
+ it('should work with an undefined sequence', () => {
175
+ const body = {};
176
+
177
+ MeetingUtil.addSequence({locusInfo: {}}, body);
178
+
179
+ assert.deepEqual(body, {});
180
+ });
181
+ });
182
+
183
+ describe('updateLocusWithDelta', () => {
184
+ it('should call handleLocusDelta with the new delta locus', () => {
139
185
  const meeting = {
140
- correlationId: 'correlation id',
141
- isMultistream: true,
142
- mediaId: '12345',
143
- meetingJoinUrl: 'meetingJoinUrl',
144
- locusUrl: 'locusUrl',
145
- deviceUrl: 'some device url',
146
- selfId: 'self id',
147
- meetingRequest: {remoteAudioVideoToggle: sinon.stub().returns(Promise.resolve({body: {}, headers: {}}))}
186
+ locusInfo: {
187
+ handleLocusDelta: sinon.stub(),
188
+ },
148
189
  };
149
190
 
150
- await MeetingUtil.remoteUpdateAudioVideo(true, false, meeting);
191
+ const originalResponse = {
192
+ body: {
193
+ locus: 'locus',
194
+ },
195
+ };
151
196
 
152
- assert.calledOnce(meeting.meetingRequest.remoteAudioVideoToggle);
153
- const parameter = meeting.meetingRequest.remoteAudioVideoToggle.getCall(0).args[0];
197
+ const response = MeetingUtil.updateLocusWithDelta(meeting, originalResponse);
154
198
 
155
- assert.equal(parameter.locusUrl, 'locusUrl');
156
- assert.equal(parameter.selfId, 'self id');
157
- assert.equal(parameter.correlationId, 'correlation id');
158
- assert.equal(parameter.deviceUrl, 'some device url');
159
- assert.deepEqual(parameter.localMedias, [{localSdp: '{"audioMuted":true,"videoMuted":false}', mediaId: '12345'}]);
160
- assert.equal(parameter.preferTranscoding, false);
199
+ assert.deepEqual(response, originalResponse);
200
+ assert.calledOnceWithExactly(meeting.locusInfo.handleLocusDelta, 'locus', meeting);
201
+ });
202
+
203
+ it('should handle locus being missing from the response', () => {
204
+ const meeting = {
205
+ locusInfo: {
206
+ handleLocusDelta: sinon.stub(),
207
+ },
208
+ };
209
+
210
+ const originalResponse = {
211
+ body: {},
212
+ };
213
+
214
+ const response = MeetingUtil.updateLocusWithDelta(meeting, originalResponse);
215
+
216
+ assert.deepEqual(response, originalResponse);
217
+ assert.notCalled(meeting.locusInfo.handleLocusDelta);
161
218
  });
162
219
 
163
- it('#Should call meetingRequest.remoteAudioVideoToggle with preferTranscoding:true for non multistream connections', async () => {
220
+ it('should work with an undefined meeting', () => {
221
+ const originalResponse = {
222
+ body: {
223
+ locus: 'locus',
224
+ },
225
+ };
226
+
227
+ const response = MeetingUtil.updateLocusWithDelta(undefined, originalResponse);
228
+ assert.deepEqual(response, originalResponse);
229
+ });
230
+ });
231
+
232
+ describe('generateLocusDeltaRequest', () => {
233
+ it('generates the correct wrapper function', async () => {
234
+ const updateLocusWithDeltaSpy = sinon.spy(MeetingUtil, 'updateLocusWithDelta');
235
+ const addSequenceSpy = sinon.spy(MeetingUtil, 'addSequence');
236
+
164
237
  const meeting = {
165
- isMultistream: false,
238
+ request: sinon.stub().returns(Promise.resolve('result')),
239
+ };
240
+
241
+ const locusDeltaRequest = MeetingUtil.generateLocusDeltaRequest(meeting);
242
+
243
+ const options = {
244
+ some: 'option',
245
+ body: {},
246
+ };
247
+
248
+ let result = await locusDeltaRequest(options);
249
+
250
+ assert.equal(result, 'result');
251
+ assert.calledOnceWithExactly(updateLocusWithDeltaSpy, meeting, 'result');
252
+ assert.calledOnceWithExactly(addSequenceSpy, meeting, options.body);
253
+
254
+ updateLocusWithDeltaSpy.resetHistory();
255
+ addSequenceSpy.resetHistory();
256
+
257
+ // body missing from options
258
+ result = await locusDeltaRequest({});
259
+ assert.equal(result, 'result');
260
+ assert.calledOnceWithExactly(updateLocusWithDeltaSpy, meeting, 'result');
261
+ assert.calledOnceWithExactly(addSequenceSpy, meeting, options.body);
262
+
263
+ // meeting disappears so the WeakRef returns undefined
264
+ sinon.stub(WeakRef.prototype, 'deref').returns(undefined);
265
+
266
+ result = await locusDeltaRequest(options);
267
+ assert.equal(result, undefined);
268
+
269
+ WeakRef.prototype.deref.restore();
270
+ });
271
+
272
+ it('calls generateBuildLocusDeltaRequestOptions as expected', () => {
273
+ const generateBuildLocusDeltaRequestOptionsSpy = sinon.spy(
274
+ MeetingUtil,
275
+ 'generateBuildLocusDeltaRequestOptions'
276
+ );
277
+
278
+ const meeting = {};
279
+
280
+ MeetingUtil.generateLocusDeltaRequest(meeting);
281
+
282
+ assert.calledOnceWithExactly(generateBuildLocusDeltaRequestOptionsSpy, meeting);
283
+ });
284
+ });
285
+
286
+ describe('selfSupportsFeature', () => {
287
+ it('returns true if there are no user policies', () => {
288
+ assert.equal(
289
+ MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_ANNOTATION, undefined),
290
+ true
291
+ );
292
+ });
293
+
294
+ it('returns true if policy is true', () => {
295
+ assert.equal(
296
+ MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_ANNOTATION, {
297
+ [SELF_POLICY.SUPPORT_ANNOTATION]: true,
298
+ }),
299
+ true
300
+ );
301
+ });
302
+
303
+ it('returns false if policy is false', () => {
304
+ assert.equal(
305
+ MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_ANNOTATION, {
306
+ [SELF_POLICY.SUPPORT_ANNOTATION]: false,
307
+ }),
308
+ false
309
+ );
310
+ });
311
+ });
312
+
313
+ describe('remoteUpdateAudioVideo', () => {
314
+ it('#Should call meetingRequest.locusMediaRequest with correct parameters', async () => {
315
+ const meeting = {
316
+ id: 'meeting-id',
166
317
  mediaId: '12345',
167
- meetingRequest: {remoteAudioVideoToggle: sinon.stub().returns(Promise.resolve({body: {}, headers: {}}))}
318
+ selfUrl: 'self url',
319
+ locusInfo: {
320
+ sequence: {},
321
+ },
322
+ locusMediaRequest: {
323
+ send: sinon.stub().resolves({body: {}, headers: {}}),
324
+ },
325
+ getWebexObject: sinon.stub().returns(webex),
168
326
  };
169
327
 
170
- await MeetingUtil.remoteUpdateAudioVideo(true, false, meeting);
328
+ await MeetingUtil.remoteUpdateAudioVideo(meeting, true, false);
171
329
 
172
- assert.calledOnce(meeting.meetingRequest.remoteAudioVideoToggle);
173
- const parameter = meeting.meetingRequest.remoteAudioVideoToggle.getCall(0).args[0];
330
+ assert.calledOnceWithExactly(meeting.locusMediaRequest.send, {
331
+ mediaId: '12345',
332
+ muteOptions: {
333
+ audioMuted: true,
334
+ videoMuted: false,
335
+ },
336
+ selfUrl: 'self url',
337
+ sequence: {},
338
+ type: 'LocalMute',
339
+ });
174
340
 
175
- assert.equal(parameter.preferTranscoding, true);
341
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
342
+ name: 'client.locus.media.request',
343
+ options: {meetingId: meeting.id},
344
+ });
345
+
346
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
347
+ name: 'client.locus.media.response',
348
+ options: {meetingId: meeting.id},
349
+ });
176
350
  });
177
351
  });
178
352
 
179
353
  describe('joinMeeting', () => {
180
354
  it('#Should call `meetingRequest.joinMeeting', async () => {
181
- const meeting = {meetingJoinUrl: 'meetingJoinUrl', locusUrl: 'locusUrl', meetingRequest: {joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}}))}};
355
+ const meeting = {
356
+ meetingJoinUrl: 'meetingJoinUrl',
357
+ locusUrl: 'locusUrl',
358
+ meetingRequest: {
359
+ joinMeeting: sinon.stub().returns(
360
+ Promise.resolve({
361
+ body: {mediaConnections: 'mediaConnections'},
362
+ headers: {
363
+ trackingid: 'trackingId',
364
+ },
365
+ })
366
+ ),
367
+ },
368
+ getWebexObject: sinon.stub().returns(webex),
369
+ };
182
370
 
183
371
  MeetingUtil.parseLocusJoin = sinon.stub();
184
372
  await MeetingUtil.joinMeeting(meeting, {});
@@ -188,6 +376,84 @@ describe('plugin-meetings', () => {
188
376
 
189
377
  assert.equal(parameter.inviteeAddress, 'meetingJoinUrl');
190
378
  assert.equal(parameter.preferTranscoding, true);
379
+
380
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
381
+ name: 'client.locus.join.request',
382
+ options: {meetingId: meeting.id},
383
+ });
384
+
385
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
386
+ name: 'client.locus.join.response',
387
+ payload: {
388
+ trigger: 'loci-update',
389
+ identifiers: {
390
+ trackingId: 'trackingId',
391
+ },
392
+ },
393
+ options: {
394
+ meetingId: meeting.id,
395
+ mediaConnections: 'mediaConnections',
396
+ },
397
+ });
398
+ });
399
+
400
+ it('#Should call meetingRequest.joinMeeting with breakoutsSupported=true when passed in as true', async () => {
401
+ const meeting = {
402
+ meetingRequest: {
403
+ joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}})),
404
+ },
405
+ getWebexObject: sinon.stub().returns(webex),
406
+ };
407
+
408
+ MeetingUtil.parseLocusJoin = sinon.stub();
409
+ await MeetingUtil.joinMeeting(meeting, {
410
+ breakoutsSupported: true,
411
+ });
412
+
413
+ assert.calledOnce(meeting.meetingRequest.joinMeeting);
414
+ const parameter = meeting.meetingRequest.joinMeeting.getCall(0).args[0];
415
+
416
+ assert.equal(parameter.breakoutsSupported, true);
417
+ });
418
+
419
+ it('#Should call meetingRequest.joinMeeting with liveAnnotationSupported=true when passed in as true', async () => {
420
+ const meeting = {
421
+ meetingRequest: {
422
+ joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}})),
423
+ },
424
+ getWebexObject: sinon.stub().returns(webex),
425
+ };
426
+
427
+ MeetingUtil.parseLocusJoin = sinon.stub();
428
+ await MeetingUtil.joinMeeting(meeting, {
429
+ liveAnnotationSupported: true,
430
+ });
431
+
432
+ assert.calledOnce(meeting.meetingRequest.joinMeeting);
433
+ const parameter = meeting.meetingRequest.joinMeeting.getCall(0).args[0];
434
+
435
+ assert.equal(parameter.liveAnnotationSupported, true);
436
+ });
437
+
438
+ it('#Should call meetingRequest.joinMeeting with locale=en_UK, deviceCapabilities=["TEST"] when they are passed in as those values', async () => {
439
+ const meeting = {
440
+ meetingRequest: {
441
+ joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}})),
442
+ },
443
+ getWebexObject: sinon.stub().returns(webex),
444
+ };
445
+
446
+ MeetingUtil.parseLocusJoin = sinon.stub();
447
+ await MeetingUtil.joinMeeting(meeting, {
448
+ locale: 'en_UK',
449
+ deviceCapabilities: ['TEST'],
450
+ });
451
+
452
+ assert.calledOnce(meeting.meetingRequest.joinMeeting);
453
+ const parameter = meeting.meetingRequest.joinMeeting.getCall(0).args[0];
454
+
455
+ assert.equal(parameter.locale, 'en_UK');
456
+ assert.deepEqual(parameter.deviceCapabilities, ['TEST']);
191
457
  });
192
458
 
193
459
  it('#Should call meetingRequest.joinMeeting with preferTranscoding=false when multistream is enabled', async () => {
@@ -195,7 +461,10 @@ describe('plugin-meetings', () => {
195
461
  isMultistream: true,
196
462
  meetingJoinUrl: 'meetingJoinUrl',
197
463
  locusUrl: 'locusUrl',
198
- meetingRequest: {joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}}))}
464
+ meetingRequest: {
465
+ joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}})),
466
+ },
467
+ getWebexObject: sinon.stub().returns(webex),
199
468
  };
200
469
 
201
470
  MeetingUtil.parseLocusJoin = sinon.stub();
@@ -209,7 +478,14 @@ describe('plugin-meetings', () => {
209
478
  });
210
479
 
211
480
  it('#Should fallback sipUrl if meetingJoinUrl does not exists', async () => {
212
- const meeting = {sipUri: 'sipUri', locusUrl: 'locusUrl', meetingRequest: {joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}}))}};
481
+ const meeting = {
482
+ sipUri: 'sipUri',
483
+ locusUrl: 'locusUrl',
484
+ meetingRequest: {
485
+ joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}})),
486
+ },
487
+ getWebexObject: sinon.stub().returns(webex),
488
+ };
213
489
 
214
490
  MeetingUtil.parseLocusJoin = sinon.stub();
215
491
  await MeetingUtil.joinMeeting(meeting, {});
@@ -221,7 +497,14 @@ describe('plugin-meetings', () => {
221
497
  });
222
498
 
223
499
  it('#Should fallback to meetingNumber if meetingJoinUrl/sipUrl does not exists', async () => {
224
- const meeting = {meetingNumber: 'meetingNumber', locusUrl: 'locusUrl', meetingRequest: {joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}}))}};
500
+ const meeting = {
501
+ meetingNumber: 'meetingNumber',
502
+ locusUrl: 'locusUrl',
503
+ meetingRequest: {
504
+ joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}})),
505
+ },
506
+ getWebexObject: sinon.stub().returns(webex),
507
+ };
225
508
 
226
509
  MeetingUtil.parseLocusJoin = sinon.stub();
227
510
  await MeetingUtil.joinMeeting(meeting, {});
@@ -232,21 +515,72 @@ describe('plugin-meetings', () => {
232
515
  assert.isUndefined(parameter.inviteeAddress);
233
516
  assert.equal(parameter.meetingNumber, 'meetingNumber');
234
517
  });
518
+
519
+ it('should pass in the locusClusterUrl from meetingInfo', async () => {
520
+ const meeting = {
521
+ meetingInfo: {
522
+ locusClusterUrl: 'locusClusterUrl',
523
+ },
524
+ meetingRequest: {
525
+ joinMeeting: sinon.stub().returns(Promise.resolve({body: {}, headers: {}})),
526
+ },
527
+ getWebexObject: sinon.stub().returns(webex),
528
+ };
529
+
530
+ MeetingUtil.parseLocusJoin = sinon.stub();
531
+ await MeetingUtil.joinMeeting(meeting, {});
532
+
533
+ assert.calledOnce(meeting.meetingRequest.joinMeeting);
534
+ const parameter = meeting.meetingRequest.joinMeeting.getCall(0).args[0];
535
+
536
+ assert.equal(parameter.locusClusterUrl, 'locusClusterUrl');
537
+ });
538
+ });
539
+
540
+ describe('joinMeetingOptions', () => {
541
+ it('sends client events correctly', async () => {
542
+ MeetingUtil.joinMeeting = sinon.stub().rejects({});
543
+ MeetingUtil.isPinOrGuest = sinon.stub().returns(true);
544
+ const meeting = {
545
+ id: 'meeting-id',
546
+ mediaId: '12345',
547
+ selfUrl: 'self url',
548
+ locusInfo: {
549
+ sequence: {},
550
+ },
551
+ locusMediaRequest: {
552
+ send: sinon.stub().resolves({body: {}, headers: {}}),
553
+ },
554
+ getWebexObject: sinon.stub().returns(webex),
555
+ };
556
+
557
+ try {
558
+ await MeetingUtil.joinMeetingOptions(meeting, {pin: true});
559
+
560
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
561
+ name: 'client.pin.collected',
562
+ options: {
563
+ meetingId: meeting.id,
564
+ },
565
+ });
566
+ } catch (err) {
567
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
568
+ name: 'client.pin.prompt',
569
+ options: {
570
+ meetingId: meeting.id,
571
+ },
572
+ });
573
+ }
574
+ });
235
575
  });
236
576
 
237
577
  describe('getUserDisplayHintsFromLocusInfo', () => {
238
578
  it('returns display hints', () => {
239
579
  assert.deepEqual(MeetingUtil.getUserDisplayHintsFromLocusInfo(), []);
240
580
 
241
- assert.deepEqual(
242
- MeetingUtil.getUserDisplayHintsFromLocusInfo({}),
243
- []
244
- );
581
+ assert.deepEqual(MeetingUtil.getUserDisplayHintsFromLocusInfo({}), []);
245
582
 
246
- assert.deepEqual(
247
- MeetingUtil.getUserDisplayHintsFromLocusInfo({parsedLocus: {}}),
248
- []
249
- );
583
+ assert.deepEqual(MeetingUtil.getUserDisplayHintsFromLocusInfo({parsedLocus: {}}), []);
250
584
 
251
585
  assert.deepEqual(
252
586
  MeetingUtil.getUserDisplayHintsFromLocusInfo({parsedLocus: {info: {}}}),
@@ -254,7 +588,9 @@ describe('plugin-meetings', () => {
254
588
  );
255
589
 
256
590
  assert.deepEqual(
257
- MeetingUtil.getUserDisplayHintsFromLocusInfo({parsedLocus: {info: {userDisplayHints: []}}}),
591
+ MeetingUtil.getUserDisplayHintsFromLocusInfo({
592
+ parsedLocus: {info: {userDisplayHints: []}},
593
+ }),
258
594
  []
259
595
  );
260
596
 
@@ -262,11 +598,9 @@ describe('plugin-meetings', () => {
262
598
  MeetingUtil.getUserDisplayHintsFromLocusInfo({
263
599
  parsedLocus: {
264
600
  info: {
265
- userDisplayHints: [
266
- 'HINT_1'
267
- ]
268
- }
269
- }
601
+ userDisplayHints: ['HINT_1'],
602
+ },
603
+ },
270
604
  }),
271
605
  ['HINT_1']
272
606
  );
@@ -303,68 +637,82 @@ describe('plugin-meetings', () => {
303
637
 
304
638
  describe('canUserLowerSomeoneElsesHand', () => {
305
639
  it('works as expected', () => {
306
- assert.deepEqual(MeetingUtil.canUserLowerSomeoneElsesHand(['LOWER_SOMEONE_ELSES_HAND']), true);
640
+ assert.deepEqual(
641
+ MeetingUtil.canUserLowerSomeoneElsesHand(['LOWER_SOMEONE_ELSES_HAND']),
642
+ true
643
+ );
307
644
  assert.deepEqual(MeetingUtil.canUserLowerSomeoneElsesHand([]), false);
308
645
  });
309
646
  });
310
647
 
311
- describe('bothLeaveAndEndMeetingAvailable', () => {
648
+ describe('canUserRenameSelfAndObserved', () => {
312
649
  it('works as expected', () => {
313
- assert.deepEqual(MeetingUtil.bothLeaveAndEndMeetingAvailable(['LEAVE_TRANSFER_HOST_END_MEETING']), true);
314
- assert.deepEqual(MeetingUtil.bothLeaveAndEndMeetingAvailable(['LEAVE_END_MEETING']), true);
315
- assert.deepEqual(MeetingUtil.bothLeaveAndEndMeetingAvailable(['LEAVE_TRANSFER_HOST_END_MEETING', 'LEAVE_END_MEETING']), true);
316
- assert.deepEqual(MeetingUtil.bothLeaveAndEndMeetingAvailable([]), false);
317
- });
318
- });
319
-
320
- describe('canUserLock', () => {
321
- it('works as expected', () => {
322
- assert.deepEqual(MeetingUtil.canUserLock(['LOCK_CONTROL_LOCK', 'LOCK_STATUS_UNLOCKED']), true);
323
- assert.deepEqual(MeetingUtil.canUserLock(['LOCK_CONTROL_LOCK']), false);
324
- assert.deepEqual(MeetingUtil.canUserLock(['LOCK_STATUS_UNLOCKED']), false);
325
- assert.deepEqual(MeetingUtil.canUserLock([]), false);
650
+ assert.deepEqual(
651
+ MeetingUtil.canUserRenameSelfAndObserved(['CAN_RENAME_SELF_AND_OBSERVED']),
652
+ true
653
+ );
654
+ assert.deepEqual(MeetingUtil.canUserRenameSelfAndObserved([]), false);
326
655
  });
327
656
  });
328
657
 
329
- describe('canUserUnlock', () => {
658
+ describe('canUserRenameOthers', () => {
330
659
  it('works as expected', () => {
331
- assert.deepEqual(MeetingUtil.canUserUnlock(['LOCK_CONTROL_UNLOCK', 'LOCK_STATUS_LOCKED']), true);
332
- assert.deepEqual(MeetingUtil.canUserUnlock(['LOCK_CONTROL_UNLOCK']), false);
333
- assert.deepEqual(MeetingUtil.canUserUnlock(['LOCK_STATUS_LOCKED']), false);
334
- assert.deepEqual(MeetingUtil.canUserUnlock([]), false);
660
+ assert.deepEqual(MeetingUtil.canUserRenameOthers(['CAN_RENAME_OTHERS']), true);
661
+ assert.deepEqual(MeetingUtil.canUserRenameOthers([]), false);
335
662
  });
336
663
  });
337
664
 
338
- describe('canUserRecord', () => {
665
+ describe('canShareWhiteBoard', () => {
339
666
  it('works as expected', () => {
340
- assert.deepEqual(MeetingUtil.canUserRecord(['RECORDING_CONTROL_START']), true);
341
- assert.deepEqual(MeetingUtil.canUserRecord([]), false);
667
+ assert.deepEqual(MeetingUtil.canShareWhiteBoard(['SHARE_WHITEBOARD']), true);
668
+ assert.deepEqual(MeetingUtil.canShareWhiteBoard([]), false);
342
669
  });
343
670
  });
344
671
 
345
- describe('canUserPause', () => {
672
+ describe('bothLeaveAndEndMeetingAvailable', () => {
346
673
  it('works as expected', () => {
347
- assert.deepEqual(MeetingUtil.canUserPause(['RECORDING_CONTROL_PAUSE']), true);
348
- assert.deepEqual(MeetingUtil.canUserPause([]), false);
674
+ assert.deepEqual(
675
+ MeetingUtil.bothLeaveAndEndMeetingAvailable(['LEAVE_TRANSFER_HOST_END_MEETING']),
676
+ true
677
+ );
678
+ assert.deepEqual(MeetingUtil.bothLeaveAndEndMeetingAvailable(['LEAVE_END_MEETING']), true);
679
+ assert.deepEqual(
680
+ MeetingUtil.bothLeaveAndEndMeetingAvailable([
681
+ 'LEAVE_TRANSFER_HOST_END_MEETING',
682
+ 'LEAVE_END_MEETING',
683
+ ]),
684
+ true
685
+ );
686
+ assert.deepEqual(MeetingUtil.bothLeaveAndEndMeetingAvailable([]), false);
349
687
  });
350
688
  });
351
689
 
352
- describe('canUserResume', () => {
690
+ describe('canUserLock', () => {
353
691
  it('works as expected', () => {
354
- assert.deepEqual(MeetingUtil.canUserResume(['RECORDING_CONTROL_RESUME']), true);
355
- assert.deepEqual(MeetingUtil.canUserResume([]), false);
692
+ assert.deepEqual(
693
+ MeetingUtil.canUserLock(['LOCK_CONTROL_LOCK', 'LOCK_STATUS_UNLOCKED']),
694
+ true
695
+ );
696
+ assert.deepEqual(MeetingUtil.canUserLock(['LOCK_CONTROL_LOCK']), false);
697
+ assert.deepEqual(MeetingUtil.canUserLock(['LOCK_STATUS_UNLOCKED']), false);
698
+ assert.deepEqual(MeetingUtil.canUserLock([]), false);
356
699
  });
357
700
  });
358
701
 
359
-
360
- describe('canUserStop', () => {
702
+ describe('canUserUnlock', () => {
361
703
  it('works as expected', () => {
362
- assert.deepEqual(MeetingUtil.canUserStop(['RECORDING_CONTROL_STOP']), true);
363
- assert.deepEqual(MeetingUtil.canUserStop([]), false);
704
+ assert.deepEqual(
705
+ MeetingUtil.canUserUnlock(['LOCK_CONTROL_UNLOCK', 'LOCK_STATUS_LOCKED']),
706
+ true
707
+ );
708
+ assert.deepEqual(MeetingUtil.canUserUnlock(['LOCK_CONTROL_UNLOCK']), false);
709
+ assert.deepEqual(MeetingUtil.canUserUnlock(['LOCK_STATUS_LOCKED']), false);
710
+ assert.deepEqual(MeetingUtil.canUserUnlock([]), false);
364
711
  });
365
712
  });
366
713
 
367
714
  [
715
+ {functionName: 'isSaveTranscriptsEnabled', displayHint: 'SAVE_TRANSCRIPTS_ENABLED'},
368
716
  {functionName: 'canEnableClosedCaption', displayHint: 'CAPTION_START'},
369
717
  {functionName: 'canStartTranscribing', displayHint: 'TRANSCRIPTION_CONTROL_START'},
370
718
  {functionName: 'canStopTranscribing', displayHint: 'TRANSCRIPTION_CONTROL_STOP'},
@@ -383,104 +731,304 @@ describe('plugin-meetings', () => {
383
731
  });
384
732
  });
385
733
 
734
+ describe('canManageBreakout', () => {
735
+ it('works as expected', () => {
736
+ assert.deepEqual(MeetingUtil.canManageBreakout(['BREAKOUT_MANAGEMENT']), true);
737
+ assert.deepEqual(MeetingUtil.canManageBreakout([]), false);
738
+ });
739
+ });
386
740
 
387
- describe('recording tests', () => {
388
- let request;
389
- let locusInfo;
390
- const locusUrl = 'locusUrl';
741
+ describe('canBroadcastMessageToBreakout', () => {
742
+ it('works as expected', () => {
743
+ assert.deepEqual(
744
+ MeetingUtil.canBroadcastMessageToBreakout(['BROADCAST_MESSAGE_TO_BREAKOUT'], {
745
+ [SELF_POLICY.SUPPORT_BROADCAST_MESSAGE]: true,
746
+ }),
747
+ true
748
+ );
749
+ assert.deepEqual(
750
+ MeetingUtil.canBroadcastMessageToBreakout([], {
751
+ [SELF_POLICY.SUPPORT_BROADCAST_MESSAGE]: true,
752
+ }),
753
+ false
754
+ );
755
+ assert.deepEqual(
756
+ MeetingUtil.canBroadcastMessageToBreakout(['BROADCAST_MESSAGE_TO_BREAKOUT'], {
757
+ [SELF_POLICY.SUPPORT_BROADCAST_MESSAGE]: false,
758
+ }),
759
+ false
760
+ );
761
+ assert.deepEqual(
762
+ MeetingUtil.canBroadcastMessageToBreakout(['BROADCAST_MESSAGE_TO_BREAKOUT'], undefined),
763
+ false
764
+ );
765
+ });
766
+ });
767
+
768
+ describe('isSuppressBreakoutSupport', () => {
769
+ it('works as expected', () => {
770
+ assert.deepEqual(
771
+ MeetingUtil.isSuppressBreakoutSupport(['UCF_SUPPRESS_BREAKOUTS_SUPPORT']),
772
+ true
773
+ );
774
+ assert.deepEqual(MeetingUtil.isSuppressBreakoutSupport([]), false);
775
+ });
776
+ });
777
+
778
+ describe('canAdmitLobbyToBreakout', () => {
779
+ it('works as expected', () => {
780
+ assert.deepEqual(MeetingUtil.canAdmitLobbyToBreakout(['DISABLE_LOBBY_TO_BREAKOUT']), false);
781
+ assert.deepEqual(MeetingUtil.canAdmitLobbyToBreakout([]), true);
782
+ });
783
+ });
784
+
785
+ describe('canUserAskForHelp', () => {
786
+ it('works as expected', () => {
787
+ assert.deepEqual(MeetingUtil.canUserAskForHelp(['DISABLE_ASK_FOR_HELP']), false);
788
+ assert.deepEqual(MeetingUtil.canUserAskForHelp([]), true);
789
+ });
790
+ });
391
791
 
792
+ describe('isBreakoutPreassignmentsEnabled', () => {
793
+ it('works as expected', () => {
794
+ assert.deepEqual(
795
+ MeetingUtil.isBreakoutPreassignmentsEnabled(['DISABLE_BREAKOUT_PREASSIGNMENTS']),
796
+ false
797
+ );
798
+ assert.deepEqual(MeetingUtil.isBreakoutPreassignmentsEnabled([]), true);
799
+ });
800
+ });
801
+
802
+ describe('parseInterpretationInfo', () => {
803
+ let meetingInfo = {};
392
804
  beforeEach(() => {
393
- locusInfo = {
394
- parsedLocus: {
395
- info: {
396
- userDisplayHints: [
397
- 'RECORDING_CONTROL_START'
398
- ]
399
- }
400
- }
401
- };
402
- request = {
403
- recordMeeting: sinon.stub().returns(Promise.resolve())
805
+ meeting.simultaneousInterpretation = {
806
+ updateMeetingSIEnabled: sinon.stub(),
807
+ updateHostSIEnabled: sinon.stub(),
808
+ updateInterpretation: sinon.stub(),
809
+ siLanguages: [],
404
810
  };
405
811
  });
812
+ it('should update simultaneous interpretation settings with SI and host enabled', () => {
813
+ meetingInfo.turnOnSimultaneousInterpretation = true;
814
+ meetingInfo.meetingSiteSetting = {
815
+ enableHostInterpreterControlSI: true,
816
+ };
817
+ meetingInfo.simultaneousInterpretation = {
818
+ currentSIInterpreter: true,
819
+ siLanguages: [
820
+ {languageCode: 'en', languageGroupId: 1},
821
+ {languageCode: 'es', languageGroupId: 2},
822
+ ],
823
+ };
406
824
 
407
- describe('startRecording', () => {
408
- it('can start recording when the correct display hint is present', () => {
409
- locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_START');
825
+ MeetingUtil.parseInterpretationInfo(meeting, meetingInfo);
826
+ assert.calledWith(meeting.simultaneousInterpretation.updateMeetingSIEnabled, true, true);
827
+ assert.calledWith(meeting.simultaneousInterpretation.updateHostSIEnabled, true);
828
+ assert.calledWith(meeting.simultaneousInterpretation.updateInterpretation, {
829
+ siLanguages: [
830
+ {languageName: 'en', languageCode: 1},
831
+ {languageName: 'es', languageCode: 2},
832
+ ],
833
+ });
834
+ });
410
835
 
411
- const result = MeetingUtil.startRecording(request, locusUrl, locusInfo);
836
+ it('should update simultaneous interpretation settings with host SI disabled', () => {
837
+ meetingInfo.meetingSiteSetting.enableHostInterpreterControlSI = false;
838
+ meetingInfo.simultaneousInterpretation.currentSIInterpreter = false;
839
+ MeetingUtil.parseInterpretationInfo(meeting, meetingInfo);
840
+ assert.calledWith(meeting.simultaneousInterpretation.updateMeetingSIEnabled, true, false);
841
+ assert.calledWith(meeting.simultaneousInterpretation.updateHostSIEnabled, false);
842
+ assert.calledWith(meeting.simultaneousInterpretation.updateInterpretation, {
843
+ siLanguages: [
844
+ {languageName: 'en', languageCode: 1},
845
+ {languageName: 'es', languageCode: 2},
846
+ ],
847
+ });
848
+ });
849
+ it('should update simultaneous interpretation settings with SI disabled', () => {
850
+ meetingInfo.turnOnSimultaneousInterpretation = false;
851
+ MeetingUtil.parseInterpretationInfo(meeting, meetingInfo);
852
+ assert.calledWith(meeting.simultaneousInterpretation.updateMeetingSIEnabled, false, false);
853
+ assert.calledWith(meeting.simultaneousInterpretation.updateHostSIEnabled, false);
854
+ });
412
855
 
413
- assert.calledWith(request.recordMeeting, {locusUrl, recording: true, paused: false});
856
+ it('should not update simultaneous interpretation settings for invalid input', () => {
857
+ // Call the function with invalid inputs
858
+ MeetingUtil.parseInterpretationInfo(null, null);
414
859
 
415
- assert.deepEqual(result, request.recordMeeting.firstCall.returnValue);
416
- });
860
+ // Ensure that the update functions are not called
861
+ assert.notCalled(meeting.simultaneousInterpretation.updateMeetingSIEnabled);
862
+ assert.notCalled(meeting.simultaneousInterpretation.updateHostSIEnabled);
863
+ assert.notCalled(meeting.simultaneousInterpretation.updateInterpretation);
864
+ });
865
+ });
417
866
 
418
- it('rejects when correct display hint is not present', () => {
419
- const result = MeetingUtil.startRecording(request, locusUrl, {});
867
+ describe('prepareLeaveMeetingOptions', () => {
868
+ it('works as expected', () => {
869
+ const meeting = {
870
+ locusUrl: 'locusUrl',
871
+ selfId: 'selfId',
872
+ correlationId: 'correlationId',
873
+ resourceId: 'resourceId',
874
+ deviceUrl: 'deviceUrl',
875
+ };
420
876
 
421
- assert.notCalled(request.recordMeeting);
877
+ const leaveOptions = MeetingUtil.prepareLeaveMeetingOptions(meeting, {
878
+ selfId: 'bob',
879
+ foo: 'bar',
880
+ });
422
881
 
423
- assert.isRejected(result);
882
+ assert.deepEqual(leaveOptions, {
883
+ correlationId: 'correlationId',
884
+ deviceUrl: 'deviceUrl',
885
+ foo: 'bar',
886
+ locusUrl: 'locusUrl',
887
+ resourceId: 'resourceId',
888
+ selfId: 'bob',
424
889
  });
425
890
  });
891
+ });
426
892
 
427
- describe('pauseRecording', () => {
428
- it('can pause recording when the correct display hint is present', () => {
429
- locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_PAUSE');
893
+ describe('leaveMeeting', () => {
894
+ it('calls prepareLeaveMeetingOptions as expected', () => {
895
+ const meeting = {
896
+ locusUrl: 'locusUrl',
897
+ selfId: 'selfId',
898
+ correlationId: 'correlationId',
899
+ resourceId: 'resourceId',
900
+ deviceUrl: 'deviceUrl',
901
+ locusInfo: {parsedLocus: {}},
902
+ meetingRequest: {
903
+ leaveMeeting: () => Promise.resolve(),
904
+ },
905
+ };
430
906
 
431
- const result = MeetingUtil.pauseRecording(request, locusUrl, locusInfo);
907
+ const prepareLeaveMeetingOptionsSpy = sinon.spy(MeetingUtil, 'prepareLeaveMeetingOptions');
432
908
 
433
- assert.calledWith(request.recordMeeting, {locusUrl, recording: true, paused: true});
909
+ MeetingUtil.leaveMeeting(meeting, {foo: 'bar'});
434
910
 
435
- assert.deepEqual(result, request.recordMeeting.firstCall.returnValue);
436
- });
911
+ assert.calledOnce(prepareLeaveMeetingOptionsSpy);
912
+ assert.deepEqual(prepareLeaveMeetingOptionsSpy.getCall(0).args[0], meeting);
913
+ assert.deepEqual(prepareLeaveMeetingOptionsSpy.getCall(0).args[1], {foo: 'bar'});
914
+ });
915
+ });
916
+
917
+ describe('buildLeaveFetchRequestOptions', () => {
918
+ it('calls expected functions', () => {
919
+ const buildLeaveMeetingRequestOptionsSpy = sinon.stub();
920
+
921
+ const meeting = {
922
+ locusUrl: 'locusUrl',
923
+ selfId: 'selfId',
924
+ correlationId: 'correlationId',
925
+ resourceId: 'resourceId',
926
+ deviceUrl: 'deviceUrl',
927
+ meetingRequest: {
928
+ leaveMeeting: () => Promise.resolve(),
929
+ buildLeaveMeetingRequestOptions: buildLeaveMeetingRequestOptionsSpy,
930
+ },
931
+ };
437
932
 
438
- it('rejects when correct display hint is not present', () => {
439
- const result = MeetingUtil.pauseRecording(request, locusUrl, {});
933
+ const prepareLeaveMeetingOptionsSpy = sinon.spy(MeetingUtil, 'prepareLeaveMeetingOptions');
440
934
 
441
- assert.notCalled(request.recordMeeting);
935
+ const options = MeetingUtil.buildLeaveFetchRequestOptions(meeting, {foo: 'bar'});
442
936
 
443
- assert.isRejected(result);
937
+ assert.calledOnce(prepareLeaveMeetingOptionsSpy);
938
+ assert.deepEqual(prepareLeaveMeetingOptionsSpy.getCall(0).args[0], meeting);
939
+ assert.deepEqual(prepareLeaveMeetingOptionsSpy.getCall(0).args[1], {foo: 'bar'});
940
+
941
+ assert.calledOnce(buildLeaveMeetingRequestOptionsSpy);
942
+ assert.deepEqual(buildLeaveMeetingRequestOptionsSpy.getCall(0).args[0], {
943
+ correlationId: 'correlationId',
944
+ deviceUrl: 'deviceUrl',
945
+ foo: 'bar',
946
+ locusUrl: 'locusUrl',
947
+ resourceId: 'resourceId',
948
+ selfId: 'selfId',
444
949
  });
445
950
  });
951
+ });
446
952
 
447
- describe('resumeRecording', () => {
448
- it('can resume recording when the correct display hint is present', () => {
449
- locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_RESUME');
953
+ describe('generateBuildLocusDeltaRequestOptions', () => {
954
+ it('generates the correct wrapper function', async () => {
955
+ const addSequenceSpy = sinon.spy(MeetingUtil, 'addSequence');
450
956
 
451
- const result = MeetingUtil.resumeRecording(request, locusUrl, locusInfo);
957
+ const meeting = {locusInfo: {sequence: 123}};
452
958
 
453
- assert.calledWith(request.recordMeeting, {locusUrl, recording: true, paused: false});
959
+ const buildLocusDeltaRequestOptions =
960
+ MeetingUtil.generateBuildLocusDeltaRequestOptions(meeting);
454
961
 
455
- assert.deepEqual(result, request.recordMeeting.firstCall.returnValue);
962
+ let result = buildLocusDeltaRequestOptions({
963
+ some: 'option',
964
+ body: {},
456
965
  });
966
+ assert.deepEqual(result, {some: 'option', body: {sequence: 123}});
967
+ assert.calledOnceWithExactly(addSequenceSpy, meeting, {sequence: 123});
457
968
 
458
- it('rejects when correct display hint is not present', () => {
459
- const result = MeetingUtil.resumeRecording(request, locusUrl, {});
969
+ addSequenceSpy.resetHistory();
460
970
 
461
- assert.notCalled(request.recordMeeting);
971
+ // body missing from options
972
+ result = buildLocusDeltaRequestOptions({});
973
+ assert.deepEqual(result, {body: {sequence: 123}});
974
+ assert.calledOnceWithExactly(addSequenceSpy, meeting, {sequence: 123});
462
975
 
463
- assert.isRejected(result);
464
- });
976
+ // meeting disappears so the WeakRef returns undefined
977
+ sinon.stub(WeakRef.prototype, 'deref').returns(undefined);
978
+
979
+ const input = {foo: 'bar'};
980
+ result = buildLocusDeltaRequestOptions(input);
981
+ assert.equal(result, input);
465
982
  });
983
+ });
466
984
 
467
- describe('stopRecording', () => {
468
- it('can stop recording when the correct display hint is present', () => {
469
- locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_STOP');
985
+ describe('getIpVersion', () => {
986
+ let isBrowserStub;
987
+ beforeEach(() => {
988
+ isBrowserStub = sinon.stub().returns(false);
470
989
 
471
- const result = MeetingUtil.stopRecording(request, locusUrl, locusInfo);
990
+ sinon.stub(BrowserDetectionModule, 'default').returns({
991
+ isBrowser: isBrowserStub,
992
+ });
993
+ });
472
994
 
473
- assert.calledWith(request.recordMeeting, {locusUrl, recording: false, paused: false});
995
+ afterEach(() => {
996
+ sinon.restore();
997
+ });
474
998
 
475
- assert.deepEqual(result, request.recordMeeting.firstCall.returnValue);
999
+ [
1000
+ {supportsIpV4: undefined, supportsIpV6: undefined, expectedOutput: IP_VERSION.unknown},
1001
+ {supportsIpV4: undefined, supportsIpV6: true, expectedOutput: IP_VERSION.only_ipv6},
1002
+ {supportsIpV4: undefined, supportsIpV6: false, expectedOutput: IP_VERSION.unknown},
1003
+ {supportsIpV4: true, supportsIpV6: undefined, expectedOutput: IP_VERSION.only_ipv4},
1004
+ {supportsIpV4: true, supportsIpV6: true, expectedOutput: IP_VERSION.ipv4_and_ipv6},
1005
+ {supportsIpV4: true, supportsIpV6: false, expectedOutput: IP_VERSION.only_ipv4},
1006
+ {supportsIpV4: false, supportsIpV6: undefined, expectedOutput: IP_VERSION.unknown},
1007
+ {supportsIpV4: false, supportsIpV6: true, expectedOutput: IP_VERSION.only_ipv6},
1008
+ {supportsIpV4: false, supportsIpV6: false, expectedOutput: IP_VERSION.unknown},
1009
+ ].forEach(({supportsIpV4, supportsIpV6, expectedOutput}) => {
1010
+ it(`returns ${expectedOutput} when supportsIpV4=${supportsIpV4} and supportsIpV6=${supportsIpV6}`, () => {
1011
+ sinon
1012
+ .stub(webex.internal.device.ipNetworkDetector, 'supportsIpV4')
1013
+ .get(() => supportsIpV4);
1014
+ sinon
1015
+ .stub(webex.internal.device.ipNetworkDetector, 'supportsIpV6')
1016
+ .get(() => supportsIpV6);
1017
+
1018
+ assert.equal(MeetingUtil.getIpVersion(webex), expectedOutput);
476
1019
  });
477
1020
 
478
- it('rejects when correct display hint is not present', () => {
479
- const result = MeetingUtil.stopRecording(request, locusUrl, {});
1021
+ it(`returns undefined when supportsIpV4=${supportsIpV4} and supportsIpV6=${supportsIpV6} and browser is firefox`, () => {
1022
+ sinon
1023
+ .stub(webex.internal.device.ipNetworkDetector, 'supportsIpV4')
1024
+ .get(() => supportsIpV4);
1025
+ sinon
1026
+ .stub(webex.internal.device.ipNetworkDetector, 'supportsIpV6')
1027
+ .get(() => supportsIpV6);
480
1028
 
481
- assert.notCalled(request.recordMeeting);
1029
+ isBrowserStub.callsFake((name) => name === 'firefox');
482
1030
 
483
- assert.isRejected(result);
1031
+ assert.equal(MeetingUtil.getIpVersion(webex), undefined);
484
1032
  });
485
1033
  });
486
1034
  });