@webex/plugin-meetings 3.0.0-beta.16 → 3.0.0-beta.161

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 (424) hide show
  1. package/README.md +45 -1
  2. package/dist/annotation/annotation.types.js +7 -0
  3. package/dist/annotation/annotation.types.js.map +1 -0
  4. package/dist/annotation/constants.js +49 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +359 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +212 -0
  9. package/dist/breakouts/breakout.js.map +1 -0
  10. package/dist/breakouts/collection.js +23 -0
  11. package/dist/breakouts/collection.js.map +1 -0
  12. package/dist/breakouts/edit-lock-error.js +52 -0
  13. package/dist/breakouts/edit-lock-error.js.map +1 -0
  14. package/dist/breakouts/events.js +43 -0
  15. package/dist/breakouts/events.js.map +1 -0
  16. package/dist/breakouts/index.js +1046 -0
  17. package/dist/breakouts/index.js.map +1 -0
  18. package/dist/breakouts/request.js +78 -0
  19. package/dist/breakouts/request.js.map +1 -0
  20. package/dist/breakouts/utils.js +67 -0
  21. package/dist/breakouts/utils.js.map +1 -0
  22. package/dist/common/errors/webex-errors.js +3 -2
  23. package/dist/common/errors/webex-errors.js.map +1 -1
  24. package/dist/common/logs/logger-proxy.js +1 -1
  25. package/dist/common/logs/logger-proxy.js.map +1 -1
  26. package/dist/config.js +6 -8
  27. package/dist/config.js.map +1 -1
  28. package/dist/constants.js +175 -26
  29. package/dist/constants.js.map +1 -1
  30. package/dist/controls-options-manager/constants.js +14 -0
  31. package/dist/controls-options-manager/constants.js.map +1 -0
  32. package/dist/controls-options-manager/enums.js +27 -0
  33. package/dist/controls-options-manager/enums.js.map +1 -0
  34. package/dist/controls-options-manager/index.js +297 -0
  35. package/dist/controls-options-manager/index.js.map +1 -0
  36. package/dist/controls-options-manager/types.js +7 -0
  37. package/dist/controls-options-manager/types.js.map +1 -0
  38. package/dist/controls-options-manager/util.js +300 -0
  39. package/dist/controls-options-manager/util.js.map +1 -0
  40. package/dist/index.js +77 -0
  41. package/dist/index.js.map +1 -1
  42. package/dist/interpretation/collection.js +23 -0
  43. package/dist/interpretation/collection.js.map +1 -0
  44. package/dist/interpretation/index.js +214 -0
  45. package/dist/interpretation/index.js.map +1 -0
  46. package/dist/interpretation/siLanguage.js +25 -0
  47. package/dist/interpretation/siLanguage.js.map +1 -0
  48. package/dist/locus-info/controlsUtils.js +92 -2
  49. package/dist/locus-info/controlsUtils.js.map +1 -1
  50. package/dist/locus-info/index.js +317 -24
  51. package/dist/locus-info/index.js.map +1 -1
  52. package/dist/locus-info/mediaSharesUtils.js +43 -1
  53. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  54. package/dist/locus-info/parser.js +2 -1
  55. package/dist/locus-info/parser.js.map +1 -1
  56. package/dist/locus-info/selfUtils.js +97 -14
  57. package/dist/locus-info/selfUtils.js.map +1 -1
  58. package/dist/media/index.js +39 -134
  59. package/dist/media/index.js.map +1 -1
  60. package/dist/media/properties.js +19 -97
  61. package/dist/media/properties.js.map +1 -1
  62. package/dist/mediaQualityMetrics/config.js +505 -493
  63. package/dist/mediaQualityMetrics/config.js.map +1 -1
  64. package/dist/meeting/in-meeting-actions.js +79 -1
  65. package/dist/meeting/in-meeting-actions.js.map +1 -1
  66. package/dist/meeting/index.js +2349 -2178
  67. package/dist/meeting/index.js.map +1 -1
  68. package/dist/meeting/locusMediaRequest.js +291 -0
  69. package/dist/meeting/locusMediaRequest.js.map +1 -0
  70. package/dist/meeting/muteState.js +229 -124
  71. package/dist/meeting/muteState.js.map +1 -1
  72. package/dist/meeting/request.js +191 -167
  73. package/dist/meeting/request.js.map +1 -1
  74. package/dist/meeting/request.type.js.map +1 -1
  75. package/dist/meeting/util.js +444 -443
  76. package/dist/meeting/util.js.map +1 -1
  77. package/dist/meeting-info/meeting-info-v2.js +157 -49
  78. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  79. package/dist/meeting-info/utilv2.js +20 -5
  80. package/dist/meeting-info/utilv2.js.map +1 -1
  81. package/dist/meetings/collection.js +22 -0
  82. package/dist/meetings/collection.js.map +1 -1
  83. package/dist/meetings/index.js +365 -73
  84. package/dist/meetings/index.js.map +1 -1
  85. package/dist/meetings/meetings.types.js +7 -0
  86. package/dist/meetings/meetings.types.js.map +1 -0
  87. package/dist/meetings/request.js +16 -12
  88. package/dist/meetings/request.js.map +1 -1
  89. package/dist/meetings/util.js +88 -1
  90. package/dist/meetings/util.js.map +1 -1
  91. package/dist/member/index.js +43 -0
  92. package/dist/member/index.js.map +1 -1
  93. package/dist/member/types.js +15 -0
  94. package/dist/member/types.js.map +1 -0
  95. package/dist/member/util.js +97 -3
  96. package/dist/member/util.js.map +1 -1
  97. package/dist/members/collection.js +10 -0
  98. package/dist/members/collection.js.map +1 -1
  99. package/dist/members/index.js +94 -11
  100. package/dist/members/index.js.map +1 -1
  101. package/dist/members/request.js +109 -39
  102. package/dist/members/request.js.map +1 -1
  103. package/dist/members/types.js +15 -0
  104. package/dist/members/types.js.map +1 -0
  105. package/dist/members/util.js +316 -233
  106. package/dist/members/util.js.map +1 -1
  107. package/dist/metrics/config.js +50 -14
  108. package/dist/metrics/config.js.map +1 -1
  109. package/dist/metrics/constants.js +3 -5
  110. package/dist/metrics/constants.js.map +1 -1
  111. package/dist/metrics/index.js +48 -29
  112. package/dist/metrics/index.js.map +1 -1
  113. package/dist/multistream/mediaRequestManager.js +265 -36
  114. package/dist/multistream/mediaRequestManager.js.map +1 -1
  115. package/dist/multistream/receiveSlot.js +52 -19
  116. package/dist/multistream/receiveSlot.js.map +1 -1
  117. package/dist/multistream/receiveSlotManager.js +53 -33
  118. package/dist/multistream/receiveSlotManager.js.map +1 -1
  119. package/dist/multistream/remoteMedia.js +44 -18
  120. package/dist/multistream/remoteMedia.js.map +1 -1
  121. package/dist/multistream/remoteMediaGroup.js +60 -3
  122. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  123. package/dist/multistream/remoteMediaManager.js +322 -103
  124. package/dist/multistream/remoteMediaManager.js.map +1 -1
  125. package/dist/networkQualityMonitor/index.js +4 -2
  126. package/dist/networkQualityMonitor/index.js.map +1 -1
  127. package/dist/reachability/index.js +117 -60
  128. package/dist/reachability/index.js.map +1 -1
  129. package/dist/reachability/request.js +12 -5
  130. package/dist/reachability/request.js.map +1 -1
  131. package/dist/reactions/constants.js +13 -0
  132. package/dist/reactions/constants.js.map +1 -0
  133. package/dist/reactions/reactions.js +2 -2
  134. package/dist/reactions/reactions.js.map +1 -1
  135. package/dist/reactions/reactions.type.js +18 -18
  136. package/dist/reactions/reactions.type.js.map +1 -1
  137. package/dist/reconnection-manager/index.js +190 -145
  138. package/dist/reconnection-manager/index.js.map +1 -1
  139. package/dist/recording-controller/enums.js +17 -0
  140. package/dist/recording-controller/enums.js.map +1 -0
  141. package/dist/recording-controller/index.js +343 -0
  142. package/dist/recording-controller/index.js.map +1 -0
  143. package/dist/recording-controller/util.js +63 -0
  144. package/dist/recording-controller/util.js.map +1 -0
  145. package/dist/roap/index.js +21 -29
  146. package/dist/roap/index.js.map +1 -1
  147. package/dist/roap/request.js +127 -92
  148. package/dist/roap/request.js.map +1 -1
  149. package/dist/roap/turnDiscovery.js +135 -53
  150. package/dist/roap/turnDiscovery.js.map +1 -1
  151. package/dist/statsAnalyzer/global.js +1 -93
  152. package/dist/statsAnalyzer/global.js.map +1 -1
  153. package/dist/statsAnalyzer/index.js +329 -314
  154. package/dist/statsAnalyzer/index.js.map +1 -1
  155. package/dist/statsAnalyzer/mqaUtil.js +103 -54
  156. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  157. package/dist/types/annotation/annotation.types.d.ts +43 -0
  158. package/dist/types/annotation/constants.d.ts +31 -0
  159. package/dist/types/annotation/index.d.ts +124 -0
  160. package/dist/types/breakouts/breakout.d.ts +8 -0
  161. package/dist/types/breakouts/collection.d.ts +5 -0
  162. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  163. package/dist/types/breakouts/events.d.ts +2 -0
  164. package/dist/types/breakouts/index.d.ts +5 -0
  165. package/dist/types/breakouts/request.d.ts +22 -0
  166. package/dist/types/breakouts/utils.d.ts +15 -0
  167. package/dist/types/common/browser-detection.d.ts +9 -0
  168. package/dist/types/common/collection.d.ts +48 -0
  169. package/dist/types/common/config.d.ts +2 -0
  170. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  171. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  172. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  173. package/dist/types/common/errors/media.d.ts +15 -0
  174. package/dist/types/common/errors/parameter.d.ts +15 -0
  175. package/dist/types/common/errors/password-error.d.ts +15 -0
  176. package/dist/types/common/errors/permission.d.ts +14 -0
  177. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  178. package/dist/types/common/errors/reconnection.d.ts +15 -0
  179. package/dist/types/common/errors/stats.d.ts +15 -0
  180. package/dist/types/common/errors/webex-errors.d.ts +69 -0
  181. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  182. package/dist/types/common/events/events-scope.d.ts +17 -0
  183. package/dist/types/common/events/events.d.ts +12 -0
  184. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  185. package/dist/types/common/events/util.d.ts +2 -0
  186. package/dist/types/common/logs/logger-config.d.ts +2 -0
  187. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  188. package/dist/types/common/logs/request.d.ts +34 -0
  189. package/dist/types/common/queue.d.ts +32 -0
  190. package/dist/types/config.d.ts +72 -0
  191. package/dist/types/constants.d.ts +987 -0
  192. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  193. package/dist/types/controls-options-manager/enums.d.ts +15 -0
  194. package/dist/types/controls-options-manager/index.d.ts +136 -0
  195. package/dist/types/controls-options-manager/types.d.ts +43 -0
  196. package/dist/types/controls-options-manager/util.d.ts +1 -0
  197. package/dist/types/index.d.ts +7 -0
  198. package/dist/types/interpretation/collection.d.ts +5 -0
  199. package/dist/types/interpretation/index.d.ts +5 -0
  200. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  201. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  202. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  203. package/dist/types/locus-info/fullState.d.ts +2 -0
  204. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  205. package/dist/types/locus-info/index.d.ts +315 -0
  206. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  207. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  208. package/dist/types/locus-info/parser.d.ts +212 -0
  209. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  210. package/dist/types/media/index.d.ts +34 -0
  211. package/dist/types/media/properties.d.ts +86 -0
  212. package/dist/types/media/util.d.ts +2 -0
  213. package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
  214. package/dist/types/meeting/in-meeting-actions.d.ts +149 -0
  215. package/dist/types/meeting/index.d.ts +1524 -0
  216. package/dist/types/meeting/locusMediaRequest.d.ts +70 -0
  217. package/dist/types/meeting/muteState.d.ts +184 -0
  218. package/dist/types/meeting/request.d.ts +270 -0
  219. package/dist/types/meeting/request.type.d.ts +11 -0
  220. package/dist/types/meeting/state.d.ts +9 -0
  221. package/dist/types/meeting/util.d.ts +75 -0
  222. package/dist/types/meeting-info/collection.d.ts +20 -0
  223. package/dist/types/meeting-info/index.d.ts +57 -0
  224. package/dist/types/meeting-info/meeting-info-v2.d.ts +122 -0
  225. package/dist/types/meeting-info/request.d.ts +22 -0
  226. package/dist/types/meeting-info/util.d.ts +2 -0
  227. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  228. package/dist/types/meetings/collection.d.ts +31 -0
  229. package/dist/types/meetings/index.d.ts +364 -0
  230. package/dist/types/meetings/meetings.types.d.ts +4 -0
  231. package/dist/types/meetings/request.d.ts +27 -0
  232. package/dist/types/meetings/util.d.ts +18 -0
  233. package/dist/types/member/index.d.ts +158 -0
  234. package/dist/types/member/types.d.ts +21 -0
  235. package/dist/types/member/util.d.ts +2 -0
  236. package/dist/types/members/collection.d.ts +29 -0
  237. package/dist/types/members/index.d.ts +353 -0
  238. package/dist/types/members/request.d.ts +114 -0
  239. package/dist/types/members/types.d.ts +24 -0
  240. package/dist/types/members/util.d.ts +210 -0
  241. package/dist/types/metrics/config.d.ts +195 -0
  242. package/dist/types/metrics/constants.d.ts +55 -0
  243. package/dist/types/metrics/index.d.ts +169 -0
  244. package/dist/types/multistream/mediaRequestManager.d.ts +118 -0
  245. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  246. package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
  247. package/dist/types/multistream/remoteMedia.d.ts +72 -0
  248. package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
  249. package/dist/types/multistream/remoteMediaManager.d.ts +277 -0
  250. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  251. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  252. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  253. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  254. package/dist/types/reachability/index.d.ts +152 -0
  255. package/dist/types/reachability/request.d.ts +37 -0
  256. package/dist/types/reactions/constants.d.ts +3 -0
  257. package/dist/types/reactions/reactions.d.ts +4 -0
  258. package/dist/types/reactions/reactions.type.d.ts +52 -0
  259. package/dist/types/reconnection-manager/index.d.ts +126 -0
  260. package/dist/types/recording-controller/enums.d.ts +7 -0
  261. package/dist/types/recording-controller/index.d.ts +193 -0
  262. package/dist/types/recording-controller/util.d.ts +13 -0
  263. package/dist/types/roap/index.d.ts +77 -0
  264. package/dist/types/roap/request.d.ts +36 -0
  265. package/dist/types/roap/turnDiscovery.d.ts +91 -0
  266. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  267. package/dist/types/statsAnalyzer/index.d.ts +200 -0
  268. package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
  269. package/dist/types/transcription/index.d.ts +64 -0
  270. package/package.json +28 -21
  271. package/src/annotation/annotation.types.ts +52 -0
  272. package/src/annotation/constants.ts +36 -0
  273. package/src/annotation/index.ts +343 -0
  274. package/src/breakouts/README.md +220 -0
  275. package/src/breakouts/breakout.ts +180 -0
  276. package/src/breakouts/collection.ts +19 -0
  277. package/src/breakouts/edit-lock-error.ts +25 -0
  278. package/src/breakouts/events.ts +37 -0
  279. package/src/breakouts/index.ts +921 -0
  280. package/src/breakouts/request.ts +55 -0
  281. package/src/breakouts/utils.ts +57 -0
  282. package/src/common/errors/webex-errors.ts +6 -2
  283. package/src/common/logs/logger-proxy.ts +1 -1
  284. package/src/config.ts +5 -7
  285. package/src/constants.ts +165 -20
  286. package/src/controls-options-manager/constants.ts +5 -0
  287. package/src/controls-options-manager/enums.ts +18 -0
  288. package/src/controls-options-manager/index.ts +278 -0
  289. package/src/controls-options-manager/types.ts +59 -0
  290. package/src/controls-options-manager/util.ts +286 -0
  291. package/src/index.ts +34 -0
  292. package/src/interpretation/README.md +51 -0
  293. package/src/interpretation/collection.ts +19 -0
  294. package/src/interpretation/index.ts +182 -0
  295. package/src/interpretation/siLanguage.ts +18 -0
  296. package/src/locus-info/controlsUtils.ts +110 -0
  297. package/src/locus-info/index.ts +339 -21
  298. package/src/locus-info/mediaSharesUtils.ts +48 -0
  299. package/src/locus-info/parser.ts +2 -1
  300. package/src/locus-info/selfUtils.ts +86 -2
  301. package/src/media/index.ts +70 -142
  302. package/src/media/properties.ts +41 -104
  303. package/src/mediaQualityMetrics/config.ts +379 -377
  304. package/src/meeting/in-meeting-actions.ts +156 -0
  305. package/src/meeting/index.ts +1779 -1741
  306. package/src/meeting/locusMediaRequest.ts +309 -0
  307. package/src/meeting/muteState.ts +228 -132
  308. package/src/meeting/request.ts +100 -91
  309. package/src/meeting/request.type.ts +2 -0
  310. package/src/meeting/util.ts +422 -421
  311. package/src/meeting-info/meeting-info-v2.ts +134 -13
  312. package/src/meeting-info/utilv2.ts +13 -3
  313. package/src/meetings/collection.ts +20 -0
  314. package/src/meetings/index.ts +385 -83
  315. package/src/meetings/meetings.types.ts +12 -0
  316. package/src/meetings/request.ts +3 -1
  317. package/src/meetings/util.ts +103 -4
  318. package/src/member/index.ts +42 -0
  319. package/src/member/types.ts +24 -0
  320. package/src/member/util.ts +95 -1
  321. package/src/members/collection.ts +8 -0
  322. package/src/members/index.ts +108 -6
  323. package/src/members/request.ts +98 -17
  324. package/src/members/types.ts +28 -0
  325. package/src/members/util.ts +319 -240
  326. package/src/metrics/config.ts +49 -10
  327. package/src/metrics/constants.ts +2 -4
  328. package/src/metrics/index.ts +43 -27
  329. package/src/multistream/mediaRequestManager.ts +337 -63
  330. package/src/multistream/receiveSlot.ts +68 -26
  331. package/src/multistream/receiveSlotManager.ts +61 -38
  332. package/src/multistream/remoteMedia.ts +29 -3
  333. package/src/multistream/remoteMediaGroup.ts +61 -2
  334. package/src/multistream/remoteMediaManager.ts +260 -66
  335. package/src/networkQualityMonitor/index.ts +6 -6
  336. package/src/reachability/index.ts +75 -25
  337. package/src/reachability/request.ts +10 -5
  338. package/src/reactions/constants.ts +4 -0
  339. package/src/reactions/reactions.ts +4 -4
  340. package/src/reactions/reactions.type.ts +28 -3
  341. package/src/reconnection-manager/index.ts +53 -32
  342. package/src/recording-controller/enums.ts +8 -0
  343. package/src/recording-controller/index.ts +315 -0
  344. package/src/recording-controller/util.ts +58 -0
  345. package/src/roap/index.ts +21 -30
  346. package/src/roap/request.ts +51 -52
  347. package/src/roap/turnDiscovery.ts +51 -27
  348. package/src/statsAnalyzer/global.ts +1 -94
  349. package/src/statsAnalyzer/index.ts +380 -390
  350. package/src/statsAnalyzer/mqaUtil.ts +106 -99
  351. package/test/integration/spec/converged-space-meetings.js +233 -0
  352. package/test/integration/spec/journey.js +331 -254
  353. package/test/integration/spec/space-meeting.js +77 -4
  354. package/test/unit/spec/annotation/index.ts +436 -0
  355. package/test/unit/spec/breakouts/breakout.ts +233 -0
  356. package/test/unit/spec/breakouts/collection.ts +15 -0
  357. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  358. package/test/unit/spec/breakouts/events.ts +77 -0
  359. package/test/unit/spec/breakouts/index.ts +1790 -0
  360. package/test/unit/spec/breakouts/request.ts +104 -0
  361. package/test/unit/spec/breakouts/utils.js +72 -0
  362. package/test/unit/spec/controls-options-manager/index.js +287 -0
  363. package/test/unit/spec/controls-options-manager/util.js +518 -0
  364. package/test/unit/spec/fixture/locus.js +1 -0
  365. package/test/unit/spec/interpretation/collection.ts +15 -0
  366. package/test/unit/spec/interpretation/index.ts +329 -0
  367. package/test/unit/spec/interpretation/siLanguage.ts +26 -0
  368. package/test/unit/spec/locus-info/controlsUtils.js +323 -30
  369. package/test/unit/spec/locus-info/index.js +680 -4
  370. package/test/unit/spec/locus-info/mediaSharesUtils.ts +22 -0
  371. package/test/unit/spec/locus-info/selfConstant.js +48 -0
  372. package/test/unit/spec/locus-info/selfUtils.js +275 -0
  373. package/test/unit/spec/media/index.ts +118 -22
  374. package/test/unit/spec/media/properties.ts +9 -9
  375. package/test/unit/spec/meeting/in-meeting-actions.ts +76 -0
  376. package/test/unit/spec/meeting/index.js +2695 -1513
  377. package/test/unit/spec/meeting/locusMediaRequest.ts +436 -0
  378. package/test/unit/spec/meeting/muteState.js +370 -208
  379. package/test/unit/spec/meeting/request.js +354 -42
  380. package/test/unit/spec/meeting/utils.js +270 -156
  381. package/test/unit/spec/meeting-info/meetinginfov2.js +383 -5
  382. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  383. package/test/unit/spec/meetings/collection.js +14 -0
  384. package/test/unit/spec/meetings/index.js +866 -120
  385. package/test/unit/spec/meetings/utils.js +206 -2
  386. package/test/unit/spec/member/index.js +31 -0
  387. package/test/unit/spec/member/util.js +408 -32
  388. package/test/unit/spec/members/index.js +320 -1
  389. package/test/unit/spec/members/request.js +206 -27
  390. package/test/unit/spec/members/utils.js +184 -0
  391. package/test/unit/spec/metrics/index.js +98 -0
  392. package/test/unit/spec/multistream/mediaRequestManager.ts +1012 -109
  393. package/test/unit/spec/multistream/receiveSlot.ts +77 -18
  394. package/test/unit/spec/multistream/receiveSlotManager.ts +69 -39
  395. package/test/unit/spec/multistream/remoteMedia.ts +32 -2
  396. package/test/unit/spec/multistream/remoteMediaGroup.ts +271 -5
  397. package/test/unit/spec/multistream/remoteMediaManager.ts +672 -65
  398. package/test/unit/spec/networkQualityMonitor/index.js +4 -4
  399. package/test/unit/spec/reachability/index.ts +176 -25
  400. package/test/unit/spec/reachability/request.js +66 -0
  401. package/test/unit/spec/reconnection-manager/index.js +46 -13
  402. package/test/unit/spec/recording-controller/index.js +231 -0
  403. package/test/unit/spec/recording-controller/util.js +102 -0
  404. package/test/unit/spec/roap/index.ts +21 -51
  405. package/test/unit/spec/roap/request.ts +187 -0
  406. package/test/unit/spec/roap/turnDiscovery.ts +73 -34
  407. package/test/unit/spec/stats-analyzer/index.js +94 -43
  408. package/test/utils/constants.js +9 -0
  409. package/test/utils/integrationTestUtils.js +46 -0
  410. package/test/utils/testUtils.js +0 -45
  411. package/test/utils/webex-config.js +4 -0
  412. package/test/utils/webex-test-users.js +7 -3
  413. package/tsconfig.json +6 -0
  414. package/dist/media/internal-media-core-wrapper.js +0 -18
  415. package/dist/media/internal-media-core-wrapper.js.map +0 -1
  416. package/dist/meeting/effectsState.js +0 -262
  417. package/dist/meeting/effectsState.js.map +0 -1
  418. package/dist/multistream/multistreamMedia.js +0 -106
  419. package/dist/multistream/multistreamMedia.js.map +0 -1
  420. package/src/index.js +0 -15
  421. package/src/media/internal-media-core-wrapper.ts +0 -9
  422. package/src/meeting/effectsState.ts +0 -211
  423. package/src/multistream/multistreamMedia.ts +0 -93
  424. package/test/unit/spec/meeting/effectsState.js +0 -281
@@ -18,7 +18,8 @@ import {
18
18
  DISPLAY_HINTS,
19
19
  } from '../../../../src/constants';
20
20
 
21
- import {self, selfWithInactivity} from './selfConstant';
21
+ import { self, selfWithInactivity } from "./selfConstant";
22
+ import uuid from "uuid";
22
23
 
23
24
  describe('plugin-meetings', () => {
24
25
  describe('LocusInfo index', () => {
@@ -66,8 +67,12 @@ describe('plugin-meetings', () => {
66
67
 
67
68
  beforeEach('setup new controls', () => {
68
69
  newControls = {
70
+ disallowUnmute: {enabled: true},
69
71
  lock: {},
70
72
  meetingFull: {},
73
+ muteOnEntry: {enabled: true},
74
+ raiseHand: {enabled: true},
75
+ reactions: {enabled: true, showDisplayNameWithReactions: true},
71
76
  record: {
72
77
  recording: false,
73
78
  paused: false,
@@ -76,12 +81,14 @@ describe('plugin-meetings', () => {
76
81
  modifiedBy: 'George Kittle',
77
82
  },
78
83
  },
79
- shareControl: {},
84
+ shareControl: {control: 'example-value'},
80
85
  transcribe: {},
86
+ viewTheParticipantList: {enabled: true},
81
87
  meetingContainer: {
82
88
  meetingContainerUrl: 'http://new-url.com',
83
89
  },
84
90
  entryExitTone: {enabled: true, mode: 'foo'},
91
+ video: {enabled: true},
85
92
  };
86
93
  });
87
94
 
@@ -95,6 +102,97 @@ describe('plugin-meetings', () => {
95
102
  assert.equal(locusInfo.controls, newControls);
96
103
  });
97
104
 
105
+ it('should trigger the CONTROLS_MUTE_ON_ENTRY_CHANGED event when necessary', () => {
106
+ locusInfo.controls = {};
107
+ locusInfo.emitScoped = sinon.stub();
108
+ locusInfo.updateControls(newControls);
109
+
110
+ assert.calledWith(
111
+ locusInfo.emitScoped,
112
+ {file: 'locus-info', function: 'updateControls'},
113
+ LOCUSINFO.EVENTS.CONTROLS_MUTE_ON_ENTRY_CHANGED,
114
+ {state: newControls.muteOnEntry},
115
+ );
116
+ });
117
+
118
+ it('should trigger the CONTROLS_SHARE_CONTROL_CHANGED event when necessary', () => {
119
+ locusInfo.controls = {};
120
+ locusInfo.emitScoped = sinon.stub();
121
+ locusInfo.updateControls(newControls);
122
+
123
+ assert.calledWith(
124
+ locusInfo.emitScoped,
125
+ {file: 'locus-info', function: 'updateControls'},
126
+ LOCUSINFO.EVENTS.CONTROLS_SHARE_CONTROL_CHANGED,
127
+ {state: newControls.shareControl},
128
+ );
129
+ });
130
+
131
+ it('should trigger the CONTROLS_DISALLOW_UNMUTE_CHANGED event when necessary', () => {
132
+ locusInfo.controls = {};
133
+ locusInfo.emitScoped = sinon.stub();
134
+ locusInfo.updateControls(newControls);
135
+
136
+ assert.calledWith(
137
+ locusInfo.emitScoped,
138
+ {file: 'locus-info', function: 'updateControls'},
139
+ LOCUSINFO.EVENTS.CONTROLS_DISALLOW_UNMUTE_CHANGED,
140
+ {state: newControls.disallowUnmute},
141
+ );
142
+ });
143
+
144
+ it('should trigger the CONTROLS_REACTIONS_CHANGED event when necessary', () => {
145
+ locusInfo.controls = {};
146
+ locusInfo.emitScoped = sinon.stub();
147
+ locusInfo.updateControls(newControls);
148
+
149
+ assert.calledWith(
150
+ locusInfo.emitScoped,
151
+ {file: 'locus-info', function: 'updateControls'},
152
+ LOCUSINFO.EVENTS.CONTROLS_REACTIONS_CHANGED,
153
+ {state: newControls.reactions},
154
+ );
155
+ });
156
+
157
+ it('should trigger the CONTROLS_VIEW_THE_PARTICIPANTS_LIST_CHANGED event when necessary', () => {
158
+ locusInfo.controls = {};
159
+ locusInfo.emitScoped = sinon.stub();
160
+ locusInfo.updateControls(newControls);
161
+
162
+ assert.calledWith(
163
+ locusInfo.emitScoped,
164
+ {file: 'locus-info', function: 'updateControls'},
165
+ LOCUSINFO.EVENTS.CONTROLS_VIEW_THE_PARTICIPANTS_LIST_CHANGED,
166
+ {state: newControls.viewTheParticipantList},
167
+ );
168
+ });
169
+
170
+ it('should trigger the CONTROLS_RAISE_HAND_CHANGED event when necessary', () => {
171
+ locusInfo.controls = {};
172
+ locusInfo.emitScoped = sinon.stub();
173
+ locusInfo.updateControls(newControls);
174
+
175
+ assert.calledWith(
176
+ locusInfo.emitScoped,
177
+ {file: 'locus-info', function: 'updateControls'},
178
+ LOCUSINFO.EVENTS.CONTROLS_RAISE_HAND_CHANGED,
179
+ {state: newControls.raiseHand},
180
+ );
181
+ });
182
+
183
+ it('should trigger the CONTROLS_VIDEO_CHANGED event when necessary', () => {
184
+ locusInfo.controls = {};
185
+ locusInfo.emitScoped = sinon.stub();
186
+ locusInfo.updateControls(newControls);
187
+
188
+ assert.calledWith(
189
+ locusInfo.emitScoped,
190
+ {file: 'locus-info', function: 'updateControls'},
191
+ LOCUSINFO.EVENTS.CONTROLS_VIDEO_CHANGED,
192
+ {state: newControls.video},
193
+ );
194
+ });
195
+
98
196
  it('should not trigger the CONTROLS_RECORDING_UPDATED event', () => {
99
197
  locusInfo.controls = {};
100
198
  locusInfo.emitScoped = sinon.stub();
@@ -277,6 +375,48 @@ describe('plugin-meetings', () => {
277
375
  );
278
376
  });
279
377
 
378
+ it('should update the breakout state', () => {
379
+ locusInfo.emitScoped = sinon.stub();
380
+ let tmpStub = sinon.stub(SelfUtils, 'getReplacedBreakoutMoveId').returns('breakoutMoveId');
381
+ newControls.breakout = { 'breakout': {} };
382
+ let selfInfo = {};
383
+
384
+ locusInfo.updateControls(newControls, selfInfo);
385
+
386
+ assert.calledWith(
387
+ locusInfo.emitScoped,
388
+ {
389
+ file: 'locus-info',
390
+ function: 'updateControls',
391
+ },
392
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_BREAKOUT_UPDATED,
393
+ {
394
+ breakout: newControls.breakout,
395
+ }
396
+ );
397
+ tmpStub.restore();
398
+ });
399
+
400
+ it('should update the interpretation state', () => {
401
+ locusInfo.emitScoped = sinon.stub();
402
+ newControls.interpretation = {siLanguages: [{languageCode: 20, languageName: 'en'}]};
403
+ let selfInfo = {};
404
+
405
+ locusInfo.updateControls(newControls, selfInfo);
406
+
407
+ assert.calledWith(
408
+ locusInfo.emitScoped,
409
+ {
410
+ file: 'locus-info',
411
+ function: 'updateControls',
412
+ },
413
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_INTERPRETATION_UPDATED,
414
+ {
415
+ interpretation: newControls.interpretation,
416
+ }
417
+ );
418
+ });
419
+
280
420
  it('should update the transcript state', () => {
281
421
  locusInfo.emitScoped = sinon.stub();
282
422
  locusInfo.controls = {
@@ -398,6 +538,39 @@ describe('plugin-meetings', () => {
398
538
  assert.notEqual(x.args[1], LOCUSINFO.EVENTS.CONTROLS_ENTRY_EXIT_TONE_UPDATED);
399
539
  });
400
540
  });
541
+
542
+ it('should update videoEnabled when changed', () => {
543
+ locusInfo.controls = {};
544
+
545
+ locusInfo.emitScoped = sinon.stub();
546
+ locusInfo.updateControls(newControls);
547
+
548
+ assert.calledWith(
549
+ locusInfo.emitScoped,
550
+ {
551
+ file: 'locus-info',
552
+ function: 'updateControls',
553
+ },
554
+ LOCUSINFO.EVENTS.SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED,
555
+ {unmuteAllowed: true}
556
+ );
557
+
558
+ assert.equal(mockMeeting.unmuteVideoAllowed, true);
559
+ });
560
+
561
+ it('should not update videoEnabled when unchanged', () => {
562
+ locusInfo.controls = {videoEnabled: true};
563
+
564
+ locusInfo.emitScoped = sinon.stub();
565
+ locusInfo.updateControls(newControls);
566
+
567
+ locusInfo.emitScoped.getCalls().forEach((x) => {
568
+ // check that no calls in emitScoped are for SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED
569
+ assert.notEqual(x.args[1], LOCUSINFO.EVENTS.SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED);
570
+ });
571
+
572
+ assert.equal(mockMeeting.unmuteVideoAllowed, undefined);
573
+ });
401
574
  });
402
575
 
403
576
  describe('#updateParticipants()', () => {
@@ -451,6 +624,7 @@ describe('plugin-meetings', () => {
451
624
  selfIdentity: '123',
452
625
  selfId: '2',
453
626
  hostId: '3',
627
+ isReplace: undefined,
454
628
  }
455
629
  );
456
630
  // note: in a real use case, recordingId, selfId, and hostId would all be the same
@@ -458,6 +632,43 @@ describe('plugin-meetings', () => {
458
632
  // are being correctly grabbed from locusInfo.parsedLocus within updateParticipants
459
633
  });
460
634
 
635
+ it('should call with breakout control info', () => {
636
+ locusInfo.parsedLocus = {
637
+ controls: {
638
+ record: {
639
+ modifiedBy: '1',
640
+ },
641
+ },
642
+ self: {
643
+ selfIdentity: '123',
644
+ selfId: '2',
645
+ },
646
+ host: {
647
+ hostId: '3',
648
+ },
649
+ };
650
+
651
+ locusInfo.emitScoped = sinon.stub();
652
+ locusInfo.updateParticipants({}, true);
653
+
654
+ assert.calledWith(
655
+ locusInfo.emitScoped,
656
+ {
657
+ file: 'locus-info',
658
+ function: 'updateParticipants',
659
+ },
660
+ EVENTS.LOCUS_INFO_UPDATE_PARTICIPANTS,
661
+ {
662
+ participants: {},
663
+ recordingId: '1',
664
+ selfIdentity: '123',
665
+ selfId: '2',
666
+ hostId: '3',
667
+ isReplace: true,
668
+ }
669
+ );
670
+ });
671
+
461
672
  it('should update the deltaParticipants object', () => {
462
673
  const prev = locusInfo.deltaParticipants;
463
674
 
@@ -664,6 +875,122 @@ describe('plugin-meetings', () => {
664
875
  );
665
876
  });
666
877
 
878
+ describe('SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED', () => {
879
+ it('should emit event when video muted on entry', () => {
880
+ // usually "previous self" is just undefined when we get first self from locus
881
+ locusInfo.self = undefined;
882
+ const selfWithMutedByOthers = cloneDeep(self);
883
+
884
+ // remoteVideoMuted
885
+ selfWithMutedByOthers.controls.video.muted = true;
886
+
887
+ locusInfo.webex.internal.device.url = self.deviceUrl;
888
+ locusInfo.emitScoped = sinon.stub();
889
+ locusInfo.updateSelf(selfWithMutedByOthers, []);
890
+
891
+ assert.calledWith(
892
+ locusInfo.emitScoped,
893
+ {
894
+ file: 'locus-info',
895
+ function: 'updateSelf',
896
+ },
897
+ LOCUSINFO.EVENTS.SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED,
898
+ {muted: true}
899
+ );
900
+
901
+ // but sometimes "previous self" is defined, but without controls.audio.muted, so we test this here:
902
+ locusInfo.self = cloneDeep(self);
903
+ locusInfo.self.controls.video = {};
904
+
905
+ locusInfo.updateSelf(selfWithMutedByOthers, []);
906
+ assert.calledWith(
907
+ locusInfo.emitScoped,
908
+ {
909
+ file: 'locus-info',
910
+ function: 'updateSelf',
911
+ },
912
+ LOCUSINFO.EVENTS.SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED,
913
+ {muted: true}
914
+ );
915
+ });
916
+
917
+ it('should not emit event when not muted on entry', () => {
918
+ locusInfo.self = undefined;
919
+ const selfWithMutedByOthersFalse = cloneDeep(self);
920
+
921
+ selfWithMutedByOthersFalse.controls.video.muted = false;
922
+
923
+ locusInfo.webex.internal.device.url = self.deviceUrl;
924
+ locusInfo.emitScoped = sinon.stub();
925
+ locusInfo.updateSelf(selfWithMutedByOthersFalse, []);
926
+
927
+ // we might get some calls to emitScoped, but we need to check that none of them are for SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED
928
+ locusInfo.emitScoped.getCalls().forEach((x) => {
929
+ assert.notEqual(x.args[1], LOCUSINFO.EVENTS.SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED);
930
+ });
931
+ });
932
+
933
+ it('should emit event when remoteVideoMuted changed', () => {
934
+ locusInfo.self = self;
935
+ const selfWithMutedByOthers = cloneDeep(self);
936
+
937
+ selfWithMutedByOthers.controls.video.muted = true;
938
+
939
+ locusInfo.webex.internal.device.url = self.deviceUrl;
940
+ locusInfo.emitScoped = sinon.stub();
941
+ locusInfo.updateSelf(selfWithMutedByOthers, []);
942
+
943
+ assert.calledWith(
944
+ locusInfo.emitScoped,
945
+ {
946
+ file: 'locus-info',
947
+ function: 'updateSelf',
948
+ },
949
+ LOCUSINFO.EVENTS.SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED,
950
+ {muted: true}
951
+ );
952
+ });
953
+ });
954
+
955
+ it('should trigger SELF_MEETING_BREAKOUTS_CHANGED when breakouts changed', () => {
956
+ locusInfo.self = self;
957
+ const selfWithBreakoutsChanged = cloneDeep(self);
958
+
959
+ selfWithBreakoutsChanged.controls.breakout.sessions.active[0].name = 'new name';
960
+
961
+ locusInfo.emitScoped = sinon.stub();
962
+ locusInfo.updateSelf(selfWithBreakoutsChanged, []);
963
+
964
+ assert.calledWith(
965
+ locusInfo.emitScoped,
966
+ {
967
+ file: 'locus-info',
968
+ function: 'updateSelf',
969
+ },
970
+ LOCUSINFO.EVENTS.SELF_MEETING_BREAKOUTS_CHANGED,
971
+ {
972
+ breakoutSessions: {
973
+ active: [
974
+ {
975
+ name: 'new name',
976
+ groupId: '0e73abb8-5584-49d8-be8d-806d2a8247ca',
977
+ sessionId: '1cf41ab1-2e57-4d95-b7e9-5613acddfb0f',
978
+ sessionType: 'BREAKOUT',
979
+ },
980
+ ],
981
+ allowed: [
982
+ {
983
+ name: 'Breakout session 2',
984
+ groupId: '0e73abb8-5584-49d8-be8d-806d2a8247ca',
985
+ sessionId: '1cf41ab1-2e57-4d95-b7e9-5613acddfb0f',
986
+ sessionType: 'BREAKOUT',
987
+ },
988
+ ],
989
+ },
990
+ }
991
+ );
992
+ });
993
+
667
994
  it('should trigger SELF_REMOTE_MUTE_STATUS_UPDATED if muted and disallowUnmute changed', () => {
668
995
  locusInfo.self = self;
669
996
  const selfWithMutedByOthersAndDissalowUnmute = cloneDeep(self);
@@ -735,6 +1062,7 @@ describe('plugin-meetings', () => {
735
1062
  const selfWithRequestedToUnmute = cloneDeep(self);
736
1063
 
737
1064
  selfWithRequestedToUnmute.controls.audio.requestedToUnmute = true;
1065
+ selfWithRequestedToUnmute.controls.audio.lastModifiedRequestedToUnmute = '2023-06-16T19:25:04.369Z';
738
1066
 
739
1067
  locusInfo.webex.internal.device.url = self.deviceUrl;
740
1068
  locusInfo.emitScoped = sinon.stub();
@@ -889,6 +1217,88 @@ describe('plugin-meetings', () => {
889
1217
  {isSharingBlocked: true}
890
1218
  );
891
1219
  });
1220
+
1221
+ it('should trigger SELF_ROLES_CHANGED if self roles changed', () => {
1222
+ locusInfo.self = self;
1223
+ locusInfo.emitScoped = sinon.stub();
1224
+ const sampleNewSelf = cloneDeep(self);
1225
+ sampleNewSelf.controls.role.roles = [{type: 'COHOST', hasRole: true}];
1226
+
1227
+ locusInfo.updateSelf(sampleNewSelf, []);
1228
+
1229
+ assert.calledWith(
1230
+ locusInfo.emitScoped,
1231
+ {
1232
+ file: 'locus-info',
1233
+ function: 'updateSelf',
1234
+ },
1235
+ LOCUSINFO.EVENTS.SELF_ROLES_CHANGED,
1236
+ {oldRoles: ['PRESENTER'], newRoles: ['COHOST']}
1237
+ );
1238
+ });
1239
+
1240
+ it('should not trigger SELF_ROLES_CHANGED if self roles not changed', () => {
1241
+ locusInfo.self = self;
1242
+ locusInfo.emitScoped = sinon.stub();
1243
+ const sampleNewSelf = cloneDeep(self);
1244
+ sampleNewSelf.controls.role.roles = [{type: 'PRESENTER', hasRole: true}];
1245
+
1246
+ locusInfo.updateSelf(sampleNewSelf, []);
1247
+
1248
+ assert.neverCalledWith(
1249
+ locusInfo.emitScoped,
1250
+ {
1251
+ file: 'locus-info',
1252
+ function: 'updateSelf',
1253
+ },
1254
+ LOCUSINFO.EVENTS.SELF_ROLES_CHANGED,
1255
+ {oldRoles: ['PRESENTER'], newRoles: ['PRESENTER']}
1256
+ );
1257
+ });
1258
+
1259
+ it('should trigger SELF_MEETING_INTERPRETATION_CHANGED if self interpretation info changed', () => {
1260
+ locusInfo.self = self;
1261
+ locusInfo.emitScoped = sinon.stub();
1262
+ const sampleNewSelf = cloneDeep(self);
1263
+ sampleNewSelf.controls.interpretation.targetLanguage = 'it';
1264
+
1265
+ locusInfo.updateSelf(sampleNewSelf, []);
1266
+
1267
+ assert.calledWith(
1268
+ locusInfo.emitScoped,
1269
+ {
1270
+ file: 'locus-info',
1271
+ function: 'updateSelf',
1272
+ },
1273
+ LOCUSINFO.EVENTS.SELF_MEETING_INTERPRETATION_CHANGED,
1274
+ {
1275
+ interpretation: sampleNewSelf.controls.interpretation,
1276
+ selfParticipantId: self.id,
1277
+ }
1278
+ );
1279
+ });
1280
+
1281
+ it('should not trigger SELF_MEETING_INTERPRETATION_CHANGED if self interpretation info not changed', () => {
1282
+ locusInfo.self = self;
1283
+ locusInfo.emitScoped = sinon.stub();
1284
+ const sampleNewSelf = cloneDeep(self);
1285
+ sampleNewSelf.controls.interpretation.targetLanguage = 'cn'; // same with previous one
1286
+
1287
+ locusInfo.updateSelf(sampleNewSelf, []);
1288
+
1289
+ assert.neverCalledWith(
1290
+ locusInfo.emitScoped,
1291
+ {
1292
+ file: 'locus-info',
1293
+ function: 'updateSelf',
1294
+ },
1295
+ LOCUSINFO.EVENTS.SELF_MEETING_INTERPRETATION_CHANGED,
1296
+ {
1297
+ interpretation: sampleNewSelf.controls.interpretation,
1298
+ selfParticipantId: self.id,
1299
+ }
1300
+ );
1301
+ });
892
1302
  });
893
1303
 
894
1304
  describe('#updateMeetingInfo', () => {
@@ -962,7 +1372,7 @@ describe('plugin-meetings', () => {
962
1372
  function: 'updateMeetingInfo',
963
1373
  },
964
1374
  LOCUSINFO.EVENTS.MEETING_INFO_UPDATED,
965
- {info: locusInfo.parsedLocus.info, self},
1375
+ {info: locusInfo.parsedLocus.info, self},
966
1376
  ];
967
1377
 
968
1378
  if (expected) {
@@ -973,6 +1383,25 @@ describe('plugin-meetings', () => {
973
1383
  locusInfo.emitScoped.resetHistory();
974
1384
  };
975
1385
 
1386
+ const checkMeetingInfoUpdatedCalledForRoles = (expected) => {
1387
+ const expectedArgs = [
1388
+ locusInfo.emitScoped,
1389
+ {
1390
+ file: 'locus-info',
1391
+ function: 'updateMeetingInfo',
1392
+ },
1393
+ LOCUSINFO.EVENTS.MEETING_INFO_UPDATED,
1394
+ ];
1395
+
1396
+ if (expected) {
1397
+ assert.calledWith(...expectedArgs);
1398
+ } else {
1399
+ assert.neverCalledWith(...expectedArgs);
1400
+ }
1401
+ locusInfo.emitScoped.resetHistory();
1402
+ };
1403
+
1404
+
976
1405
  it('emits MEETING_INFO_UPDATED if the info changes', () => {
977
1406
  const initialInfo = cloneDeep(meetingInfo);
978
1407
 
@@ -998,6 +1427,16 @@ describe('plugin-meetings', () => {
998
1427
 
999
1428
  // since the info is the same it should not call trigger the event
1000
1429
  checkMeetingInfoUpdatedCalled(false);
1430
+
1431
+ // update it with the same info, but roles changed
1432
+ const updateSelf = cloneDeep(self);
1433
+ updateSelf?.controls?.role?.roles.push({
1434
+ type: 'COHOST',
1435
+ hasRole: true,
1436
+ });
1437
+ locusInfo.updateMeetingInfo(newInfo, updateSelf);
1438
+ // since the info is the same but roles changed, it should call trigger the event
1439
+ checkMeetingInfoUpdatedCalledForRoles(true);
1001
1440
  });
1002
1441
 
1003
1442
  it('gets roles from self if available', () => {
@@ -1103,6 +1542,7 @@ describe('plugin-meetings', () => {
1103
1542
  fakeLocus = {
1104
1543
  meeting: true,
1105
1544
  participants: true,
1545
+ url: 'newLocusUrl',
1106
1546
  };
1107
1547
  });
1108
1548
 
@@ -1147,6 +1587,55 @@ describe('plugin-meetings', () => {
1147
1587
  assert.isFunction(locusParser.onDeltaAction);
1148
1588
  });
1149
1589
 
1590
+ it('#updateLocusInfo ignores breakout LEFT message', () => {
1591
+ const newLocus = {
1592
+ self: {
1593
+ reason: 'MOVED',
1594
+ state: 'LEFT',
1595
+ },
1596
+ };
1597
+
1598
+ locusInfo.updateControls = sinon.stub();
1599
+ locusInfo.updateConversationUrl = sinon.stub();
1600
+ locusInfo.updateCreated = sinon.stub();
1601
+ locusInfo.updateFullState = sinon.stub();
1602
+ locusInfo.updateHostInfo = sinon.stub();
1603
+ locusInfo.updateMeetingInfo = sinon.stub();
1604
+ locusInfo.updateMediaShares = sinon.stub();
1605
+ locusInfo.updateParticipantsUrl = sinon.stub();
1606
+ locusInfo.updateReplace = sinon.stub();
1607
+ locusInfo.updateSelf = sinon.stub();
1608
+ locusInfo.updateLocusUrl = sinon.stub();
1609
+ locusInfo.updateAclUrl = sinon.stub();
1610
+ locusInfo.updateBasequence = sinon.stub();
1611
+ locusInfo.updateSequence = sinon.stub();
1612
+ locusInfo.updateMemberShip = sinon.stub();
1613
+ locusInfo.updateIdentifiers = sinon.stub();
1614
+ locusInfo.updateEmbeddedApps = sinon.stub();
1615
+ locusInfo.compareAndUpdate = sinon.stub();
1616
+
1617
+ locusInfo.updateLocusInfo(newLocus);
1618
+
1619
+ assert.notCalled(locusInfo.updateControls);
1620
+ assert.notCalled(locusInfo.updateConversationUrl);
1621
+ assert.notCalled(locusInfo.updateCreated);
1622
+ assert.notCalled(locusInfo.updateFullState);
1623
+ assert.notCalled(locusInfo.updateHostInfo);
1624
+ assert.notCalled(locusInfo.updateMeetingInfo);
1625
+ assert.notCalled(locusInfo.updateMediaShares);
1626
+ assert.notCalled(locusInfo.updateParticipantsUrl);
1627
+ assert.notCalled(locusInfo.updateReplace);
1628
+ assert.notCalled(locusInfo.updateSelf);
1629
+ assert.notCalled(locusInfo.updateLocusUrl);
1630
+ assert.notCalled(locusInfo.updateAclUrl);
1631
+ assert.notCalled(locusInfo.updateBasequence);
1632
+ assert.notCalled(locusInfo.updateSequence);
1633
+ assert.notCalled(locusInfo.updateMemberShip);
1634
+ assert.notCalled(locusInfo.updateIdentifiers);
1635
+ assert.notCalled(locusInfo.updateEmbeddedApps);
1636
+ assert.notCalled(locusInfo.compareAndUpdate);
1637
+ });
1638
+
1150
1639
  it('onFullLocus() updates the working-copy of locus parser', () => {
1151
1640
  const eventType = 'fakeEvent';
1152
1641
 
@@ -1196,12 +1685,18 @@ describe('plugin-meetings', () => {
1196
1685
  locusInfo: {
1197
1686
  onFullLocus: sandbox.stub(),
1198
1687
  },
1688
+ locusUrl: 'oldLocusUrl',
1199
1689
  };
1200
1690
 
1201
1691
  locusInfo.locusParser.resume = sandbox.stub();
1202
1692
  locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
1203
1693
 
1204
- assert.calledOnce(meeting.meetingRequest.getFullLocus);
1694
+ assert.calledOnceWithExactly(meeting.meetingRequest.getFullLocus,
1695
+ {
1696
+ desync: true,
1697
+ locusUrl: 'newLocusUrl',
1698
+ }
1699
+ );
1205
1700
  });
1206
1701
 
1207
1702
  it('getFullLocus handles DESYNC action correctly', () => {
@@ -1226,6 +1721,187 @@ describe('plugin-meetings', () => {
1226
1721
  assert.calledOnce(locusInfo.locusParser.resume);
1227
1722
  });
1228
1723
  });
1724
+
1725
+ it('onDeltaLocus handle delta data', () => {
1726
+ fakeLocus.participants = {};
1727
+ const fakeBreakout = {
1728
+ sessionId: 'sessionId',
1729
+ groupId: 'groupId',
1730
+ };
1731
+
1732
+ fakeLocus.controls = {
1733
+ breakout: fakeBreakout
1734
+ };
1735
+ locusInfo.controls = {
1736
+ breakout: {
1737
+ sessionId: 'sessionId',
1738
+ groupId: 'groupId',
1739
+ }
1740
+ }
1741
+ locusInfo.updateParticipants = sinon.stub();
1742
+ locusInfo.onDeltaLocus(fakeLocus);
1743
+ assert.calledWith(locusInfo.updateParticipants, {}, false);
1744
+
1745
+ fakeLocus.controls.breakout.sessionId = 'sessionId2';
1746
+ locusInfo.onDeltaLocus(fakeLocus);
1747
+ assert.calledWith(locusInfo.updateParticipants, {}, true);
1748
+ });
1749
+ });
1750
+
1751
+ describe('#updateLocusCache', () => {
1752
+ it('cache it if income locus is main session locus', () => {
1753
+ const locus = {url: 'url'};
1754
+ locusInfo.mainSessionLocusCache = null;
1755
+ locusInfo.updateLocusCache(locus);
1756
+
1757
+ assert.deepEqual(locusInfo.mainSessionLocusCache, locus);
1758
+ });
1759
+
1760
+ it('not cache it if income locus is breakout session locus', () => {
1761
+ const locus = {url: 'url', controls: {breakout: {sessionType: 'BREAKOUT'}}};
1762
+ locusInfo.mainSessionLocusCache = null;
1763
+ locusInfo.updateLocusCache(locus);
1764
+
1765
+ assert.isNull(locusInfo.mainSessionLocusCache);
1766
+ });
1767
+ });
1768
+
1769
+ describe('#getTheLocusToUpdate', () => {
1770
+ it('return the cache locus if return to main session', () => {
1771
+ locusInfo.mainSessionLocusCache = {url: 'url'};
1772
+ locusInfo.controls = {
1773
+ breakout: {
1774
+ sessionType: 'BREAKOUT'
1775
+ }
1776
+ }
1777
+ const newLocus = {
1778
+ controls: {
1779
+ breakout: {
1780
+ sessionType: 'MAIN',
1781
+ },
1782
+ },
1783
+ };
1784
+
1785
+ assert.deepEqual(locusInfo.getTheLocusToUpdate(newLocus), {url: 'url'});
1786
+ });
1787
+
1788
+ it('return the new locus if return to main session but no cache', () => {
1789
+ locusInfo.mainSessionLocusCache = null;
1790
+ locusInfo.controls = {
1791
+ breakout: {
1792
+ sessionType: 'BREAKOUT'
1793
+ }
1794
+ }
1795
+ const newLocus = {
1796
+ controls: {
1797
+ breakout: {
1798
+ sessionType: 'MAIN',
1799
+ },
1800
+ },
1801
+ };
1802
+
1803
+ assert.deepEqual(locusInfo.getTheLocusToUpdate(newLocus), newLocus);
1804
+ });
1805
+
1806
+ it('return the new locus if not return to main session', () => {
1807
+ locusInfo.mainSessionLocusCache = {url: 'url'};
1808
+ locusInfo.controls = {
1809
+ breakout: {
1810
+ sessionType: 'MAIN'
1811
+ }
1812
+ }
1813
+ const newLocus = {
1814
+ controls: {
1815
+ breakout: {
1816
+ sessionType: 'BREAKOUT',
1817
+ },
1818
+ },
1819
+ };
1820
+
1821
+ assert.deepEqual(locusInfo.getTheLocusToUpdate(newLocus), newLocus);
1822
+ });
1823
+ });
1824
+
1825
+ describe('#mergeParticipants', () => {
1826
+ let participants;
1827
+ let sourceParticipants;
1828
+ beforeEach(() => {
1829
+ participants = [{id: '111', status: 'JOINED'}, {id: '222'}];
1830
+ sourceParticipants = [{id: '111', status: 'LEFT'}, {id: '333'}];
1831
+ });
1832
+
1833
+ it('merge the participants, replace it by id if exist in old array', () => {
1834
+ const result = locusInfo.mergeParticipants(participants, sourceParticipants);
1835
+ assert.deepEqual(result, [{id: '111', status: 'LEFT'}, {id: '222'}, {id: '333'}]);
1836
+ });
1837
+
1838
+ it('return new participants if previous participants is empty', () => {
1839
+ const result = locusInfo.mergeParticipants([], sourceParticipants);
1840
+ assert.deepEqual(result, sourceParticipants);
1841
+ });
1842
+
1843
+ it('return new participants if previous participants is null/undefined', () => {
1844
+ let result = locusInfo.mergeParticipants(null, sourceParticipants);
1845
+ assert.deepEqual(result, sourceParticipants);
1846
+
1847
+ result = locusInfo.mergeParticipants(undefined, sourceParticipants);
1848
+ assert.deepEqual(result, sourceParticipants);
1849
+ });
1850
+
1851
+ it('return previous participants if new participants is empty', () => {
1852
+ const result = locusInfo.mergeParticipants(participants, []);
1853
+ assert.deepEqual(result, participants);
1854
+ });
1855
+
1856
+ it('return previous participants if new participants is null/undefined', () => {
1857
+ let result = locusInfo.mergeParticipants(participants, null);
1858
+ assert.deepEqual(result, participants);
1859
+
1860
+ result = locusInfo.mergeParticipants(participants, undefined);
1861
+ assert.deepEqual(result, participants);
1862
+ });
1863
+ });
1864
+
1865
+ describe('#updateMainSessionLocusCache', () => {
1866
+ let cachedLocus;
1867
+ let newLocus;
1868
+ beforeEach(() => {
1869
+ cachedLocus = {controls: {}, participants: [], info: {webExMeetingId: 'testId1', topic: 'test'}};
1870
+ newLocus = {self: {}, participants: [{id: '111'}], info: {testId: 'testId2', webExMeetingName: 'hello'}};
1871
+ });
1872
+ it('shallow merge new locus into cache', () => {
1873
+ locusInfo.mainSessionLocusCache = cachedLocus;
1874
+ locusInfo.updateMainSessionLocusCache(newLocus);
1875
+
1876
+ assert.deepEqual(locusInfo.mainSessionLocusCache, {
1877
+ controls: {},
1878
+ participants: [{id: '111'}],
1879
+ info: {testId: 'testId2', webExMeetingName: 'hello'},
1880
+ self: {},
1881
+ });
1882
+ });
1883
+
1884
+ it('cache new locus if no cache before', () => {
1885
+ locusInfo.mainSessionLocusCache = null;
1886
+ locusInfo.updateMainSessionLocusCache(newLocus);
1887
+
1888
+ assert.deepEqual(locusInfo.mainSessionLocusCache, newLocus);
1889
+ });
1890
+
1891
+ it('do nothing if new locus is null', () => {
1892
+ locusInfo.mainSessionLocusCache = cachedLocus;
1893
+ locusInfo.updateMainSessionLocusCache(null);
1894
+
1895
+ assert.deepEqual(locusInfo.mainSessionLocusCache, cachedLocus);
1896
+ });
1897
+ });
1898
+
1899
+ describe('#clearMainSessionLocusCache', () => {
1900
+ it('clear main session locus cache', () => {
1901
+ locusInfo.mainSessionLocusCache = {controls: {}};
1902
+ locusInfo.clearMainSessionLocusCache();
1903
+ assert.isNull(locusInfo.mainSessionLocusCache);
1904
+ })
1229
1905
  });
1230
1906
 
1231
1907
  describe('#handleOneonOneEvent', () => {