@webex/plugin-meetings 3.0.0-beta.4 → 3.0.0-beta.400

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