@webex/plugin-meetings 3.0.0-beta.18 → 3.0.0-beta.180

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 (410) hide show
  1. package/README.md +45 -7
  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 +342 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +114 -14
  9. package/dist/breakouts/breakout.js.map +1 -1
  10. package/dist/breakouts/edit-lock-error.js +52 -0
  11. package/dist/breakouts/edit-lock-error.js.map +1 -0
  12. package/dist/breakouts/events.js +45 -0
  13. package/dist/breakouts/events.js.map +1 -0
  14. package/dist/breakouts/index.js +841 -19
  15. package/dist/breakouts/index.js.map +1 -1
  16. package/dist/breakouts/request.js +78 -0
  17. package/dist/breakouts/request.js.map +1 -0
  18. package/dist/breakouts/utils.js +67 -0
  19. package/dist/breakouts/utils.js.map +1 -0
  20. package/dist/common/errors/webex-errors.js +3 -2
  21. package/dist/common/errors/webex-errors.js.map +1 -1
  22. package/dist/common/logs/logger-proxy.js +1 -1
  23. package/dist/common/logs/logger-proxy.js.map +1 -1
  24. package/dist/config.js +3 -8
  25. package/dist/config.js.map +1 -1
  26. package/dist/constants.js +172 -30
  27. package/dist/constants.js.map +1 -1
  28. package/dist/controls-options-manager/constants.js +14 -0
  29. package/dist/controls-options-manager/constants.js.map +1 -0
  30. package/dist/controls-options-manager/enums.js +27 -0
  31. package/dist/controls-options-manager/enums.js.map +1 -0
  32. package/dist/controls-options-manager/index.js +297 -0
  33. package/dist/controls-options-manager/index.js.map +1 -0
  34. package/dist/controls-options-manager/types.js +7 -0
  35. package/dist/controls-options-manager/types.js.map +1 -0
  36. package/dist/controls-options-manager/util.js +300 -0
  37. package/dist/controls-options-manager/util.js.map +1 -0
  38. package/dist/index.js +107 -0
  39. package/dist/index.js.map +1 -1
  40. package/dist/interpretation/collection.js +23 -0
  41. package/dist/interpretation/collection.js.map +1 -0
  42. package/dist/interpretation/index.js +352 -0
  43. package/dist/interpretation/index.js.map +1 -0
  44. package/dist/interpretation/siLanguage.js +25 -0
  45. package/dist/interpretation/siLanguage.js.map +1 -0
  46. package/dist/locus-info/controlsUtils.js +91 -2
  47. package/dist/locus-info/controlsUtils.js.map +1 -1
  48. package/dist/locus-info/index.js +302 -41
  49. package/dist/locus-info/index.js.map +1 -1
  50. package/dist/locus-info/mediaSharesUtils.js +43 -1
  51. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  52. package/dist/locus-info/parser.js +1 -1
  53. package/dist/locus-info/parser.js.map +1 -1
  54. package/dist/locus-info/selfUtils.js +89 -14
  55. package/dist/locus-info/selfUtils.js.map +1 -1
  56. package/dist/media/index.js +39 -134
  57. package/dist/media/index.js.map +1 -1
  58. package/dist/media/properties.js +29 -90
  59. package/dist/media/properties.js.map +1 -1
  60. package/dist/mediaQualityMetrics/config.js +505 -493
  61. package/dist/mediaQualityMetrics/config.js.map +1 -1
  62. package/dist/meeting/in-meeting-actions.js +76 -2
  63. package/dist/meeting/in-meeting-actions.js.map +1 -1
  64. package/dist/meeting/index.js +2610 -2465
  65. package/dist/meeting/index.js.map +1 -1
  66. package/dist/meeting/locusMediaRequest.js +291 -0
  67. package/dist/meeting/locusMediaRequest.js.map +1 -0
  68. package/dist/meeting/muteState.js +229 -124
  69. package/dist/meeting/muteState.js.map +1 -1
  70. package/dist/meeting/request.js +189 -146
  71. package/dist/meeting/request.js.map +1 -1
  72. package/dist/meeting/util.js +478 -414
  73. package/dist/meeting/util.js.map +1 -1
  74. package/dist/meeting-info/index.js +48 -7
  75. package/dist/meeting-info/index.js.map +1 -1
  76. package/dist/meeting-info/meeting-info-v2.js +171 -51
  77. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  78. package/dist/meeting-info/utilv2.js +20 -5
  79. package/dist/meeting-info/utilv2.js.map +1 -1
  80. package/dist/meetings/collection.js +22 -0
  81. package/dist/meetings/collection.js.map +1 -1
  82. package/dist/meetings/index.js +350 -65
  83. package/dist/meetings/index.js.map +1 -1
  84. package/dist/meetings/meetings.types.js +7 -0
  85. package/dist/meetings/meetings.types.js.map +1 -0
  86. package/dist/meetings/request.js +2 -0
  87. package/dist/meetings/request.js.map +1 -1
  88. package/dist/meetings/util.js +88 -1
  89. package/dist/meetings/util.js.map +1 -1
  90. package/dist/member/index.js +49 -0
  91. package/dist/member/index.js.map +1 -1
  92. package/dist/member/types.js +25 -0
  93. package/dist/member/types.js.map +1 -0
  94. package/dist/member/util.js +98 -2
  95. package/dist/member/util.js.map +1 -1
  96. package/dist/members/collection.js +10 -0
  97. package/dist/members/collection.js.map +1 -1
  98. package/dist/members/index.js +86 -5
  99. package/dist/members/index.js.map +1 -1
  100. package/dist/members/request.js +106 -38
  101. package/dist/members/request.js.map +1 -1
  102. package/dist/members/types.js +15 -0
  103. package/dist/members/types.js.map +1 -0
  104. package/dist/members/util.js +316 -233
  105. package/dist/members/util.js.map +1 -1
  106. package/dist/metrics/constants.js +3 -5
  107. package/dist/metrics/constants.js.map +1 -1
  108. package/dist/metrics/index.js +1 -468
  109. package/dist/metrics/index.js.map +1 -1
  110. package/dist/multistream/mediaRequestManager.js +238 -49
  111. package/dist/multistream/mediaRequestManager.js.map +1 -1
  112. package/dist/multistream/receiveSlot.js +49 -16
  113. package/dist/multistream/receiveSlot.js.map +1 -1
  114. package/dist/multistream/receiveSlotManager.js +48 -30
  115. package/dist/multistream/receiveSlotManager.js.map +1 -1
  116. package/dist/multistream/remoteMedia.js +44 -18
  117. package/dist/multistream/remoteMedia.js.map +1 -1
  118. package/dist/multistream/remoteMediaGroup.js +60 -3
  119. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  120. package/dist/multistream/remoteMediaManager.js +173 -59
  121. package/dist/multistream/remoteMediaManager.js.map +1 -1
  122. package/dist/networkQualityMonitor/index.js +4 -2
  123. package/dist/networkQualityMonitor/index.js.map +1 -1
  124. package/dist/reachability/index.js +72 -27
  125. package/dist/reachability/index.js.map +1 -1
  126. package/dist/reachability/request.js +12 -5
  127. package/dist/reachability/request.js.map +1 -1
  128. package/dist/reactions/reactions.js +2 -2
  129. package/dist/reactions/reactions.js.map +1 -1
  130. package/dist/reactions/reactions.type.js +18 -18
  131. package/dist/reactions/reactions.type.js.map +1 -1
  132. package/dist/reconnection-manager/index.js +196 -155
  133. package/dist/reconnection-manager/index.js.map +1 -1
  134. package/dist/recording-controller/index.js +21 -1
  135. package/dist/recording-controller/index.js.map +1 -1
  136. package/dist/recording-controller/util.js +9 -8
  137. package/dist/recording-controller/util.js.map +1 -1
  138. package/dist/roap/index.js +21 -29
  139. package/dist/roap/index.js.map +1 -1
  140. package/dist/roap/request.js +110 -89
  141. package/dist/roap/request.js.map +1 -1
  142. package/dist/roap/turnDiscovery.js +93 -36
  143. package/dist/roap/turnDiscovery.js.map +1 -1
  144. package/dist/statsAnalyzer/global.js +1 -93
  145. package/dist/statsAnalyzer/global.js.map +1 -1
  146. package/dist/statsAnalyzer/index.js +326 -311
  147. package/dist/statsAnalyzer/index.js.map +1 -1
  148. package/dist/statsAnalyzer/mqaUtil.js +90 -53
  149. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  150. package/dist/types/annotation/annotation.types.d.ts +42 -0
  151. package/dist/types/annotation/constants.d.ts +31 -0
  152. package/dist/types/annotation/index.d.ts +117 -0
  153. package/dist/types/breakouts/breakout.d.ts +8 -0
  154. package/dist/types/breakouts/collection.d.ts +5 -0
  155. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  156. package/dist/types/breakouts/events.d.ts +8 -0
  157. package/dist/types/breakouts/index.d.ts +5 -0
  158. package/dist/types/breakouts/request.d.ts +22 -0
  159. package/dist/types/breakouts/utils.d.ts +15 -0
  160. package/dist/types/common/browser-detection.d.ts +9 -0
  161. package/dist/types/common/collection.d.ts +48 -0
  162. package/dist/types/common/config.d.ts +2 -0
  163. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  164. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  165. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  166. package/dist/types/common/errors/media.d.ts +15 -0
  167. package/dist/types/common/errors/parameter.d.ts +15 -0
  168. package/dist/types/common/errors/password-error.d.ts +15 -0
  169. package/dist/types/common/errors/permission.d.ts +14 -0
  170. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  171. package/dist/types/common/errors/reconnection.d.ts +15 -0
  172. package/dist/types/common/errors/stats.d.ts +15 -0
  173. package/dist/types/common/errors/webex-errors.d.ts +69 -0
  174. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  175. package/dist/types/common/events/events-scope.d.ts +17 -0
  176. package/dist/types/common/events/events.d.ts +12 -0
  177. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  178. package/dist/types/common/events/util.d.ts +2 -0
  179. package/dist/types/common/logs/logger-config.d.ts +2 -0
  180. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  181. package/dist/types/common/logs/request.d.ts +34 -0
  182. package/dist/types/common/queue.d.ts +32 -0
  183. package/dist/types/config.d.ts +72 -0
  184. package/dist/types/constants.d.ts +1016 -0
  185. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  186. package/dist/types/controls-options-manager/enums.d.ts +15 -0
  187. package/dist/types/controls-options-manager/index.d.ts +136 -0
  188. package/dist/types/controls-options-manager/types.d.ts +43 -0
  189. package/dist/types/controls-options-manager/util.d.ts +1 -0
  190. package/dist/types/index.d.ts +7 -0
  191. package/dist/types/interpretation/collection.d.ts +5 -0
  192. package/dist/types/interpretation/index.d.ts +5 -0
  193. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  194. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  195. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  196. package/dist/types/locus-info/fullState.d.ts +2 -0
  197. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  198. package/dist/types/locus-info/index.d.ts +315 -0
  199. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  200. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  201. package/dist/types/locus-info/parser.d.ts +212 -0
  202. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  203. package/dist/types/media/index.d.ts +34 -0
  204. package/dist/types/media/properties.d.ts +93 -0
  205. package/dist/types/media/util.d.ts +2 -0
  206. package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
  207. package/dist/types/meeting/in-meeting-actions.d.ts +149 -0
  208. package/dist/types/meeting/index.d.ts +1467 -0
  209. package/dist/types/meeting/locusMediaRequest.d.ts +70 -0
  210. package/dist/types/meeting/muteState.d.ts +184 -0
  211. package/dist/types/meeting/request.d.ts +270 -0
  212. package/dist/types/meeting/request.type.d.ts +11 -0
  213. package/dist/types/meeting/state.d.ts +9 -0
  214. package/dist/types/meeting/util.d.ts +77 -0
  215. package/dist/types/meeting-info/collection.d.ts +20 -0
  216. package/dist/types/meeting-info/index.d.ts +62 -0
  217. package/dist/types/meeting-info/meeting-info-v2.d.ts +122 -0
  218. package/dist/types/meeting-info/request.d.ts +22 -0
  219. package/dist/types/meeting-info/util.d.ts +2 -0
  220. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  221. package/dist/types/meetings/collection.d.ts +31 -0
  222. package/dist/types/meetings/index.d.ts +365 -0
  223. package/dist/types/meetings/meetings.types.d.ts +4 -0
  224. package/dist/types/meetings/request.d.ts +27 -0
  225. package/dist/types/meetings/util.d.ts +18 -0
  226. package/dist/types/member/index.d.ts +159 -0
  227. package/dist/types/member/types.d.ts +32 -0
  228. package/dist/types/member/util.d.ts +2 -0
  229. package/dist/types/members/collection.d.ts +29 -0
  230. package/dist/types/members/index.d.ts +353 -0
  231. package/dist/types/members/request.d.ts +114 -0
  232. package/dist/types/members/types.d.ts +24 -0
  233. package/dist/types/members/util.d.ts +210 -0
  234. package/dist/types/metrics/constants.d.ts +55 -0
  235. package/dist/types/metrics/index.d.ts +45 -0
  236. package/dist/types/multistream/mediaRequestManager.d.ts +118 -0
  237. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  238. package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
  239. package/dist/types/multistream/remoteMedia.d.ts +72 -0
  240. package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
  241. package/dist/types/multistream/remoteMediaManager.d.ts +277 -0
  242. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  243. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  244. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  245. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  246. package/dist/types/reachability/index.d.ts +152 -0
  247. package/dist/types/reachability/request.d.ts +37 -0
  248. package/dist/types/reactions/constants.d.ts +3 -0
  249. package/dist/types/reactions/reactions.d.ts +4 -0
  250. package/dist/types/reactions/reactions.type.d.ts +52 -0
  251. package/dist/types/reconnection-manager/index.d.ts +126 -0
  252. package/dist/types/recording-controller/enums.d.ts +7 -0
  253. package/dist/types/recording-controller/index.d.ts +208 -0
  254. package/dist/types/recording-controller/util.d.ts +14 -0
  255. package/dist/types/roap/index.d.ts +77 -0
  256. package/dist/types/roap/request.d.ts +36 -0
  257. package/dist/types/roap/turnDiscovery.d.ts +91 -0
  258. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  259. package/dist/types/statsAnalyzer/index.d.ts +200 -0
  260. package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
  261. package/dist/types/transcription/index.d.ts +64 -0
  262. package/package.json +26 -23
  263. package/src/annotation/annotation.types.ts +50 -0
  264. package/src/annotation/constants.ts +36 -0
  265. package/src/annotation/index.ts +328 -0
  266. package/src/breakouts/README.md +44 -14
  267. package/src/breakouts/breakout.ts +87 -9
  268. package/src/breakouts/edit-lock-error.ts +25 -0
  269. package/src/breakouts/events.ts +56 -0
  270. package/src/breakouts/index.ts +710 -10
  271. package/src/breakouts/request.ts +55 -0
  272. package/src/breakouts/utils.ts +57 -0
  273. package/src/common/errors/webex-errors.ts +6 -2
  274. package/src/common/logs/logger-proxy.ts +1 -1
  275. package/src/config.ts +2 -7
  276. package/src/constants.ts +157 -21
  277. package/src/controls-options-manager/constants.ts +5 -0
  278. package/src/controls-options-manager/enums.ts +18 -0
  279. package/src/controls-options-manager/index.ts +278 -0
  280. package/src/controls-options-manager/types.ts +59 -0
  281. package/src/controls-options-manager/util.ts +286 -0
  282. package/src/index.ts +39 -0
  283. package/src/interpretation/README.md +60 -0
  284. package/src/interpretation/collection.ts +19 -0
  285. package/src/interpretation/index.ts +318 -0
  286. package/src/interpretation/siLanguage.ts +18 -0
  287. package/src/locus-info/controlsUtils.ts +108 -0
  288. package/src/locus-info/index.ts +316 -38
  289. package/src/locus-info/mediaSharesUtils.ts +48 -0
  290. package/src/locus-info/parser.ts +1 -1
  291. package/src/locus-info/selfUtils.ts +81 -5
  292. package/src/media/index.ts +77 -142
  293. package/src/media/properties.ts +49 -90
  294. package/src/mediaQualityMetrics/config.ts +379 -377
  295. package/src/meeting/in-meeting-actions.ts +151 -3
  296. package/src/meeting/index.ts +1919 -2002
  297. package/src/meeting/locusMediaRequest.ts +309 -0
  298. package/src/meeting/muteState.ts +228 -132
  299. package/src/meeting/request.ts +96 -65
  300. package/src/meeting/util.ts +464 -396
  301. package/src/meeting-info/index.ts +54 -8
  302. package/src/meeting-info/meeting-info-v2.ts +148 -14
  303. package/src/meeting-info/utilv2.ts +13 -3
  304. package/src/meetings/collection.ts +20 -0
  305. package/src/meetings/index.ts +386 -84
  306. package/src/meetings/meetings.types.ts +12 -0
  307. package/src/meetings/request.ts +2 -0
  308. package/src/meetings/util.ts +103 -4
  309. package/src/member/index.ts +49 -0
  310. package/src/member/types.ts +38 -0
  311. package/src/member/util.ts +103 -0
  312. package/src/members/collection.ts +8 -0
  313. package/src/members/index.ts +107 -6
  314. package/src/members/request.ts +97 -17
  315. package/src/members/types.ts +28 -0
  316. package/src/members/util.ts +319 -240
  317. package/src/metrics/constants.ts +2 -4
  318. package/src/metrics/index.ts +1 -490
  319. package/src/multistream/mediaRequestManager.ts +289 -79
  320. package/src/multistream/receiveSlot.ts +55 -18
  321. package/src/multistream/receiveSlotManager.ts +42 -20
  322. package/src/multistream/remoteMedia.ts +28 -2
  323. package/src/multistream/remoteMediaGroup.ts +59 -0
  324. package/src/multistream/remoteMediaManager.ts +113 -32
  325. package/src/networkQualityMonitor/index.ts +6 -6
  326. package/src/reachability/index.ts +62 -15
  327. package/src/reachability/request.ts +10 -5
  328. package/src/reactions/reactions.ts +4 -4
  329. package/src/reactions/reactions.type.ts +3 -3
  330. package/src/reconnection-manager/index.ts +68 -43
  331. package/src/recording-controller/index.ts +20 -2
  332. package/src/recording-controller/util.ts +26 -9
  333. package/src/roap/index.ts +21 -30
  334. package/src/roap/request.ts +101 -95
  335. package/src/roap/turnDiscovery.ts +47 -25
  336. package/src/statsAnalyzer/global.ts +1 -94
  337. package/src/statsAnalyzer/index.ts +376 -386
  338. package/src/statsAnalyzer/mqaUtil.ts +100 -99
  339. package/test/integration/spec/converged-space-meetings.js +233 -0
  340. package/test/integration/spec/journey.js +336 -259
  341. package/test/integration/spec/space-meeting.js +77 -4
  342. package/test/unit/spec/annotation/index.ts +418 -0
  343. package/test/unit/spec/breakouts/breakout.ts +142 -24
  344. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  345. package/test/unit/spec/breakouts/events.ts +89 -0
  346. package/test/unit/spec/breakouts/index.ts +1545 -48
  347. package/test/unit/spec/breakouts/request.ts +104 -0
  348. package/test/unit/spec/breakouts/utils.js +72 -0
  349. package/test/unit/spec/controls-options-manager/index.js +287 -0
  350. package/test/unit/spec/controls-options-manager/util.js +518 -0
  351. package/test/unit/spec/fixture/locus.js +1 -0
  352. package/test/unit/spec/interpretation/collection.ts +15 -0
  353. package/test/unit/spec/interpretation/index.ts +570 -0
  354. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  355. package/test/unit/spec/locus-info/controlsUtils.js +316 -43
  356. package/test/unit/spec/locus-info/index.js +707 -22
  357. package/test/unit/spec/locus-info/mediaSharesUtils.ts +22 -0
  358. package/test/unit/spec/locus-info/selfConstant.js +27 -4
  359. package/test/unit/spec/locus-info/selfUtils.js +208 -17
  360. package/test/unit/spec/media/index.ts +129 -23
  361. package/test/unit/spec/meeting/in-meeting-actions.ts +75 -3
  362. package/test/unit/spec/meeting/index.js +2728 -1397
  363. package/test/unit/spec/meeting/locusMediaRequest.ts +436 -0
  364. package/test/unit/spec/meeting/muteState.js +370 -208
  365. package/test/unit/spec/meeting/request.js +338 -43
  366. package/test/unit/spec/meeting/utils.js +378 -55
  367. package/test/unit/spec/meeting-info/index.js +181 -0
  368. package/test/unit/spec/meeting-info/meetinginfov2.js +383 -5
  369. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  370. package/test/unit/spec/meetings/collection.js +14 -0
  371. package/test/unit/spec/meetings/index.js +846 -121
  372. package/test/unit/spec/meetings/utils.js +206 -2
  373. package/test/unit/spec/member/index.js +58 -4
  374. package/test/unit/spec/member/util.js +415 -33
  375. package/test/unit/spec/members/index.js +320 -1
  376. package/test/unit/spec/members/request.js +206 -27
  377. package/test/unit/spec/members/utils.js +184 -0
  378. package/test/unit/spec/metrics/index.js +1 -50
  379. package/test/unit/spec/multistream/mediaRequestManager.ts +803 -162
  380. package/test/unit/spec/multistream/receiveSlot.ts +72 -13
  381. package/test/unit/spec/multistream/receiveSlotManager.ts +58 -28
  382. package/test/unit/spec/multistream/remoteMedia.ts +30 -0
  383. package/test/unit/spec/multistream/remoteMediaGroup.ts +266 -0
  384. package/test/unit/spec/multistream/remoteMediaManager.ts +318 -0
  385. package/test/unit/spec/networkQualityMonitor/index.js +4 -4
  386. package/test/unit/spec/reachability/index.ts +125 -8
  387. package/test/unit/spec/reachability/request.js +66 -0
  388. package/test/unit/spec/reconnection-manager/index.js +59 -6
  389. package/test/unit/spec/recording-controller/index.js +294 -218
  390. package/test/unit/spec/recording-controller/util.js +223 -96
  391. package/test/unit/spec/roap/index.ts +26 -51
  392. package/test/unit/spec/roap/request.ts +196 -85
  393. package/test/unit/spec/roap/turnDiscovery.ts +30 -7
  394. package/test/unit/spec/stats-analyzer/index.js +92 -41
  395. package/test/utils/constants.js +9 -0
  396. package/test/utils/integrationTestUtils.js +46 -0
  397. package/test/utils/testUtils.js +0 -45
  398. package/test/utils/webex-config.js +4 -0
  399. package/test/utils/webex-test-users.js +6 -3
  400. package/dist/meeting/effectsState.js +0 -262
  401. package/dist/meeting/effectsState.js.map +0 -1
  402. package/dist/metrics/config.js +0 -299
  403. package/dist/metrics/config.js.map +0 -1
  404. package/dist/multistream/multistreamMedia.js +0 -110
  405. package/dist/multistream/multistreamMedia.js.map +0 -1
  406. package/src/index.js +0 -15
  407. package/src/meeting/effectsState.ts +0 -211
  408. package/src/metrics/config.ts +0 -495
  409. package/src/multistream/multistreamMedia.ts +0 -97
  410. package/test/unit/spec/meeting/effectsState.js +0 -285
@@ -16,9 +16,14 @@ import {
16
16
  LOCUSEVENT,
17
17
  EVENTS,
18
18
  DISPLAY_HINTS,
19
+ _CALL_,
20
+ LOCUS,
21
+ MEETING_STATE,
22
+ _MEETING_,
19
23
  } from '../../../../src/constants';
20
24
 
21
- import {self, selfWithInactivity} from './selfConstant';
25
+ import { self, selfWithInactivity } from "./selfConstant";
26
+ import uuid from "uuid";
22
27
 
23
28
  describe('plugin-meetings', () => {
24
29
  describe('LocusInfo index', () => {
@@ -66,8 +71,12 @@ describe('plugin-meetings', () => {
66
71
 
67
72
  beforeEach('setup new controls', () => {
68
73
  newControls = {
74
+ disallowUnmute: {enabled: true},
69
75
  lock: {},
70
76
  meetingFull: {},
77
+ muteOnEntry: {enabled: true},
78
+ raiseHand: {enabled: true},
79
+ reactions: {enabled: true, showDisplayNameWithReactions: true},
71
80
  record: {
72
81
  recording: false,
73
82
  paused: false,
@@ -76,12 +85,14 @@ describe('plugin-meetings', () => {
76
85
  modifiedBy: 'George Kittle',
77
86
  },
78
87
  },
79
- shareControl: {},
88
+ shareControl: {control: 'example-value'},
80
89
  transcribe: {},
90
+ viewTheParticipantList: {enabled: true},
81
91
  meetingContainer: {
82
92
  meetingContainerUrl: 'http://new-url.com',
83
93
  },
84
94
  entryExitTone: {enabled: true, mode: 'foo'},
95
+ video: {enabled: true},
85
96
  };
86
97
  });
87
98
 
@@ -95,6 +106,97 @@ describe('plugin-meetings', () => {
95
106
  assert.equal(locusInfo.controls, newControls);
96
107
  });
97
108
 
109
+ it('should trigger the CONTROLS_MUTE_ON_ENTRY_CHANGED event when necessary', () => {
110
+ locusInfo.controls = {};
111
+ locusInfo.emitScoped = sinon.stub();
112
+ locusInfo.updateControls(newControls);
113
+
114
+ assert.calledWith(
115
+ locusInfo.emitScoped,
116
+ {file: 'locus-info', function: 'updateControls'},
117
+ LOCUSINFO.EVENTS.CONTROLS_MUTE_ON_ENTRY_CHANGED,
118
+ {state: newControls.muteOnEntry},
119
+ );
120
+ });
121
+
122
+ it('should trigger the CONTROLS_SHARE_CONTROL_CHANGED event when necessary', () => {
123
+ locusInfo.controls = {};
124
+ locusInfo.emitScoped = sinon.stub();
125
+ locusInfo.updateControls(newControls);
126
+
127
+ assert.calledWith(
128
+ locusInfo.emitScoped,
129
+ {file: 'locus-info', function: 'updateControls'},
130
+ LOCUSINFO.EVENTS.CONTROLS_SHARE_CONTROL_CHANGED,
131
+ {state: newControls.shareControl},
132
+ );
133
+ });
134
+
135
+ it('should trigger the CONTROLS_DISALLOW_UNMUTE_CHANGED event when necessary', () => {
136
+ locusInfo.controls = {};
137
+ locusInfo.emitScoped = sinon.stub();
138
+ locusInfo.updateControls(newControls);
139
+
140
+ assert.calledWith(
141
+ locusInfo.emitScoped,
142
+ {file: 'locus-info', function: 'updateControls'},
143
+ LOCUSINFO.EVENTS.CONTROLS_DISALLOW_UNMUTE_CHANGED,
144
+ {state: newControls.disallowUnmute},
145
+ );
146
+ });
147
+
148
+ it('should trigger the CONTROLS_REACTIONS_CHANGED event when necessary', () => {
149
+ locusInfo.controls = {};
150
+ locusInfo.emitScoped = sinon.stub();
151
+ locusInfo.updateControls(newControls);
152
+
153
+ assert.calledWith(
154
+ locusInfo.emitScoped,
155
+ {file: 'locus-info', function: 'updateControls'},
156
+ LOCUSINFO.EVENTS.CONTROLS_REACTIONS_CHANGED,
157
+ {state: newControls.reactions},
158
+ );
159
+ });
160
+
161
+ it('should trigger the CONTROLS_VIEW_THE_PARTICIPANTS_LIST_CHANGED event when necessary', () => {
162
+ locusInfo.controls = {};
163
+ locusInfo.emitScoped = sinon.stub();
164
+ locusInfo.updateControls(newControls);
165
+
166
+ assert.calledWith(
167
+ locusInfo.emitScoped,
168
+ {file: 'locus-info', function: 'updateControls'},
169
+ LOCUSINFO.EVENTS.CONTROLS_VIEW_THE_PARTICIPANTS_LIST_CHANGED,
170
+ {state: newControls.viewTheParticipantList},
171
+ );
172
+ });
173
+
174
+ it('should trigger the CONTROLS_RAISE_HAND_CHANGED event when necessary', () => {
175
+ locusInfo.controls = {};
176
+ locusInfo.emitScoped = sinon.stub();
177
+ locusInfo.updateControls(newControls);
178
+
179
+ assert.calledWith(
180
+ locusInfo.emitScoped,
181
+ {file: 'locus-info', function: 'updateControls'},
182
+ LOCUSINFO.EVENTS.CONTROLS_RAISE_HAND_CHANGED,
183
+ {state: newControls.raiseHand},
184
+ );
185
+ });
186
+
187
+ it('should trigger the CONTROLS_VIDEO_CHANGED event when necessary', () => {
188
+ locusInfo.controls = {};
189
+ locusInfo.emitScoped = sinon.stub();
190
+ locusInfo.updateControls(newControls);
191
+
192
+ assert.calledWith(
193
+ locusInfo.emitScoped,
194
+ {file: 'locus-info', function: 'updateControls'},
195
+ LOCUSINFO.EVENTS.CONTROLS_VIDEO_CHANGED,
196
+ {state: newControls.video},
197
+ );
198
+ });
199
+
98
200
  it('should not trigger the CONTROLS_RECORDING_UPDATED event', () => {
99
201
  locusInfo.controls = {};
100
202
  locusInfo.emitScoped = sinon.stub();
@@ -279,9 +381,11 @@ describe('plugin-meetings', () => {
279
381
 
280
382
  it('should update the breakout state', () => {
281
383
  locusInfo.emitScoped = sinon.stub();
282
- newControls.breakout = 'new breakout';
384
+ let tmpStub = sinon.stub(SelfUtils, 'getReplacedBreakoutMoveId').returns('breakoutMoveId');
385
+ newControls.breakout = { 'breakout': {} };
386
+ let selfInfo = {};
283
387
 
284
- locusInfo.updateControls(newControls);
388
+ locusInfo.updateControls(newControls, selfInfo);
285
389
 
286
390
  assert.calledWith(
287
391
  locusInfo.emitScoped,
@@ -291,7 +395,28 @@ describe('plugin-meetings', () => {
291
395
  },
292
396
  LOCUSINFO.EVENTS.CONTROLS_MEETING_BREAKOUT_UPDATED,
293
397
  {
294
- breakout: 'new breakout'
398
+ breakout: newControls.breakout,
399
+ }
400
+ );
401
+ tmpStub.restore();
402
+ });
403
+
404
+ it('should update the interpretation state', () => {
405
+ locusInfo.emitScoped = sinon.stub();
406
+ newControls.interpretation = {siLanguages: [{languageCode: 20, languageName: 'en'}]};
407
+ let selfInfo = {};
408
+
409
+ locusInfo.updateControls(newControls, selfInfo);
410
+
411
+ assert.calledWith(
412
+ locusInfo.emitScoped,
413
+ {
414
+ file: 'locus-info',
415
+ function: 'updateControls',
416
+ },
417
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_INTERPRETATION_UPDATED,
418
+ {
419
+ interpretation: newControls.interpretation,
295
420
  }
296
421
  );
297
422
  });
@@ -417,6 +542,39 @@ describe('plugin-meetings', () => {
417
542
  assert.notEqual(x.args[1], LOCUSINFO.EVENTS.CONTROLS_ENTRY_EXIT_TONE_UPDATED);
418
543
  });
419
544
  });
545
+
546
+ it('should update videoEnabled when changed', () => {
547
+ locusInfo.controls = {};
548
+
549
+ locusInfo.emitScoped = sinon.stub();
550
+ locusInfo.updateControls(newControls);
551
+
552
+ assert.calledWith(
553
+ locusInfo.emitScoped,
554
+ {
555
+ file: 'locus-info',
556
+ function: 'updateControls',
557
+ },
558
+ LOCUSINFO.EVENTS.SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED,
559
+ {unmuteAllowed: true}
560
+ );
561
+
562
+ assert.equal(mockMeeting.unmuteVideoAllowed, true);
563
+ });
564
+
565
+ it('should not update videoEnabled when unchanged', () => {
566
+ locusInfo.controls = {videoEnabled: true};
567
+
568
+ locusInfo.emitScoped = sinon.stub();
569
+ locusInfo.updateControls(newControls);
570
+
571
+ locusInfo.emitScoped.getCalls().forEach((x) => {
572
+ // check that no calls in emitScoped are for SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED
573
+ assert.notEqual(x.args[1], LOCUSINFO.EVENTS.SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED);
574
+ });
575
+
576
+ assert.equal(mockMeeting.unmuteVideoAllowed, undefined);
577
+ });
420
578
  });
421
579
 
422
580
  describe('#updateParticipants()', () => {
@@ -470,6 +628,7 @@ describe('plugin-meetings', () => {
470
628
  selfIdentity: '123',
471
629
  selfId: '2',
472
630
  hostId: '3',
631
+ isReplace: undefined,
473
632
  }
474
633
  );
475
634
  // note: in a real use case, recordingId, selfId, and hostId would all be the same
@@ -477,6 +636,43 @@ describe('plugin-meetings', () => {
477
636
  // are being correctly grabbed from locusInfo.parsedLocus within updateParticipants
478
637
  });
479
638
 
639
+ it('should call with breakout control info', () => {
640
+ locusInfo.parsedLocus = {
641
+ controls: {
642
+ record: {
643
+ modifiedBy: '1',
644
+ },
645
+ },
646
+ self: {
647
+ selfIdentity: '123',
648
+ selfId: '2',
649
+ },
650
+ host: {
651
+ hostId: '3',
652
+ },
653
+ };
654
+
655
+ locusInfo.emitScoped = sinon.stub();
656
+ locusInfo.updateParticipants({}, true);
657
+
658
+ assert.calledWith(
659
+ locusInfo.emitScoped,
660
+ {
661
+ file: 'locus-info',
662
+ function: 'updateParticipants',
663
+ },
664
+ EVENTS.LOCUS_INFO_UPDATE_PARTICIPANTS,
665
+ {
666
+ participants: {},
667
+ recordingId: '1',
668
+ selfIdentity: '123',
669
+ selfId: '2',
670
+ hostId: '3',
671
+ isReplace: true,
672
+ }
673
+ );
674
+ });
675
+
480
676
  it('should update the deltaParticipants object', () => {
481
677
  const prev = locusInfo.deltaParticipants;
482
678
 
@@ -683,6 +879,83 @@ describe('plugin-meetings', () => {
683
879
  );
684
880
  });
685
881
 
882
+ describe('SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED', () => {
883
+ it('should emit event when video muted on entry', () => {
884
+ // usually "previous self" is just undefined when we get first self from locus
885
+ locusInfo.self = undefined;
886
+ const selfWithMutedByOthers = cloneDeep(self);
887
+
888
+ // remoteVideoMuted
889
+ selfWithMutedByOthers.controls.video.muted = true;
890
+
891
+ locusInfo.webex.internal.device.url = self.deviceUrl;
892
+ locusInfo.emitScoped = sinon.stub();
893
+ locusInfo.updateSelf(selfWithMutedByOthers, []);
894
+
895
+ assert.calledWith(
896
+ locusInfo.emitScoped,
897
+ {
898
+ file: 'locus-info',
899
+ function: 'updateSelf',
900
+ },
901
+ LOCUSINFO.EVENTS.SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED,
902
+ {muted: true}
903
+ );
904
+
905
+ // but sometimes "previous self" is defined, but without controls.audio.muted, so we test this here:
906
+ locusInfo.self = cloneDeep(self);
907
+ locusInfo.self.controls.video = {};
908
+
909
+ locusInfo.updateSelf(selfWithMutedByOthers, []);
910
+ assert.calledWith(
911
+ locusInfo.emitScoped,
912
+ {
913
+ file: 'locus-info',
914
+ function: 'updateSelf',
915
+ },
916
+ LOCUSINFO.EVENTS.SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED,
917
+ {muted: true}
918
+ );
919
+ });
920
+
921
+ it('should not emit event when not muted on entry', () => {
922
+ locusInfo.self = undefined;
923
+ const selfWithMutedByOthersFalse = cloneDeep(self);
924
+
925
+ selfWithMutedByOthersFalse.controls.video.muted = false;
926
+
927
+ locusInfo.webex.internal.device.url = self.deviceUrl;
928
+ locusInfo.emitScoped = sinon.stub();
929
+ locusInfo.updateSelf(selfWithMutedByOthersFalse, []);
930
+
931
+ // we might get some calls to emitScoped, but we need to check that none of them are for SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED
932
+ locusInfo.emitScoped.getCalls().forEach((x) => {
933
+ assert.notEqual(x.args[1], LOCUSINFO.EVENTS.SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED);
934
+ });
935
+ });
936
+
937
+ it('should emit event when remoteVideoMuted changed', () => {
938
+ locusInfo.self = self;
939
+ const selfWithMutedByOthers = cloneDeep(self);
940
+
941
+ selfWithMutedByOthers.controls.video.muted = true;
942
+
943
+ locusInfo.webex.internal.device.url = self.deviceUrl;
944
+ locusInfo.emitScoped = sinon.stub();
945
+ locusInfo.updateSelf(selfWithMutedByOthers, []);
946
+
947
+ assert.calledWith(
948
+ locusInfo.emitScoped,
949
+ {
950
+ file: 'locus-info',
951
+ function: 'updateSelf',
952
+ },
953
+ LOCUSINFO.EVENTS.SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED,
954
+ {muted: true}
955
+ );
956
+ });
957
+ });
958
+
686
959
  it('should trigger SELF_MEETING_BREAKOUTS_CHANGED when breakouts changed', () => {
687
960
  locusInfo.self = self;
688
961
  const selfWithBreakoutsChanged = cloneDeep(self);
@@ -701,19 +974,23 @@ describe('plugin-meetings', () => {
701
974
  LOCUSINFO.EVENTS.SELF_MEETING_BREAKOUTS_CHANGED,
702
975
  {
703
976
  breakoutSessions: {
704
- active: [{
705
- name: 'new name',
706
- groupId: '0e73abb8-5584-49d8-be8d-806d2a8247ca',
707
- sessionId: '1cf41ab1-2e57-4d95-b7e9-5613acddfb0f',
708
- sessionType: 'BREAKOUT'
709
- }],
710
- allowed: [{
711
- name: 'Breakout session 2',
712
- groupId: '0e73abb8-5584-49d8-be8d-806d2a8247ca',
713
- sessionId: '1cf41ab1-2e57-4d95-b7e9-5613acddfb0f',
714
- sessionType: 'BREAKOUT'
715
- }]
716
- }
977
+ active: [
978
+ {
979
+ name: 'new name',
980
+ groupId: '0e73abb8-5584-49d8-be8d-806d2a8247ca',
981
+ sessionId: '1cf41ab1-2e57-4d95-b7e9-5613acddfb0f',
982
+ sessionType: 'BREAKOUT',
983
+ },
984
+ ],
985
+ allowed: [
986
+ {
987
+ name: 'Breakout session 2',
988
+ groupId: '0e73abb8-5584-49d8-be8d-806d2a8247ca',
989
+ sessionId: '1cf41ab1-2e57-4d95-b7e9-5613acddfb0f',
990
+ sessionType: 'BREAKOUT',
991
+ },
992
+ ],
993
+ },
717
994
  }
718
995
  );
719
996
  });
@@ -789,6 +1066,7 @@ describe('plugin-meetings', () => {
789
1066
  const selfWithRequestedToUnmute = cloneDeep(self);
790
1067
 
791
1068
  selfWithRequestedToUnmute.controls.audio.requestedToUnmute = true;
1069
+ selfWithRequestedToUnmute.controls.audio.lastModifiedRequestedToUnmute = '2023-06-16T19:25:04.369Z';
792
1070
 
793
1071
  locusInfo.webex.internal.device.url = self.deviceUrl;
794
1072
  locusInfo.emitScoped = sinon.stub();
@@ -943,6 +1221,88 @@ describe('plugin-meetings', () => {
943
1221
  {isSharingBlocked: true}
944
1222
  );
945
1223
  });
1224
+
1225
+ it('should trigger SELF_ROLES_CHANGED if self roles changed', () => {
1226
+ locusInfo.self = self;
1227
+ locusInfo.emitScoped = sinon.stub();
1228
+ const sampleNewSelf = cloneDeep(self);
1229
+ sampleNewSelf.controls.role.roles = [{type: 'COHOST', hasRole: true}];
1230
+
1231
+ locusInfo.updateSelf(sampleNewSelf, []);
1232
+
1233
+ assert.calledWith(
1234
+ locusInfo.emitScoped,
1235
+ {
1236
+ file: 'locus-info',
1237
+ function: 'updateSelf',
1238
+ },
1239
+ LOCUSINFO.EVENTS.SELF_ROLES_CHANGED,
1240
+ {oldRoles: ['PRESENTER'], newRoles: ['COHOST']}
1241
+ );
1242
+ });
1243
+
1244
+ it('should not trigger SELF_ROLES_CHANGED if self roles not changed', () => {
1245
+ locusInfo.self = self;
1246
+ locusInfo.emitScoped = sinon.stub();
1247
+ const sampleNewSelf = cloneDeep(self);
1248
+ sampleNewSelf.controls.role.roles = [{type: 'PRESENTER', hasRole: true}];
1249
+
1250
+ locusInfo.updateSelf(sampleNewSelf, []);
1251
+
1252
+ assert.neverCalledWith(
1253
+ locusInfo.emitScoped,
1254
+ {
1255
+ file: 'locus-info',
1256
+ function: 'updateSelf',
1257
+ },
1258
+ LOCUSINFO.EVENTS.SELF_ROLES_CHANGED,
1259
+ {oldRoles: ['PRESENTER'], newRoles: ['PRESENTER']}
1260
+ );
1261
+ });
1262
+
1263
+ it('should trigger SELF_MEETING_INTERPRETATION_CHANGED if self interpretation info changed', () => {
1264
+ locusInfo.self = self;
1265
+ locusInfo.emitScoped = sinon.stub();
1266
+ const sampleNewSelf = cloneDeep(self);
1267
+ sampleNewSelf.controls.interpretation.targetLanguage = 'it';
1268
+
1269
+ locusInfo.updateSelf(sampleNewSelf, []);
1270
+
1271
+ assert.calledWith(
1272
+ locusInfo.emitScoped,
1273
+ {
1274
+ file: 'locus-info',
1275
+ function: 'updateSelf',
1276
+ },
1277
+ LOCUSINFO.EVENTS.SELF_MEETING_INTERPRETATION_CHANGED,
1278
+ {
1279
+ interpretation: sampleNewSelf.controls.interpretation,
1280
+ selfParticipantId: self.id,
1281
+ }
1282
+ );
1283
+ });
1284
+
1285
+ it('should not trigger SELF_MEETING_INTERPRETATION_CHANGED if self interpretation info not changed', () => {
1286
+ locusInfo.self = self;
1287
+ locusInfo.emitScoped = sinon.stub();
1288
+ const sampleNewSelf = cloneDeep(self);
1289
+ sampleNewSelf.controls.interpretation.targetLanguage = 'cn'; // same with previous one
1290
+
1291
+ locusInfo.updateSelf(sampleNewSelf, []);
1292
+
1293
+ assert.neverCalledWith(
1294
+ locusInfo.emitScoped,
1295
+ {
1296
+ file: 'locus-info',
1297
+ function: 'updateSelf',
1298
+ },
1299
+ LOCUSINFO.EVENTS.SELF_MEETING_INTERPRETATION_CHANGED,
1300
+ {
1301
+ interpretation: sampleNewSelf.controls.interpretation,
1302
+ selfParticipantId: self.id,
1303
+ }
1304
+ );
1305
+ });
946
1306
  });
947
1307
 
948
1308
  describe('#updateMeetingInfo', () => {
@@ -1016,7 +1376,7 @@ describe('plugin-meetings', () => {
1016
1376
  function: 'updateMeetingInfo',
1017
1377
  },
1018
1378
  LOCUSINFO.EVENTS.MEETING_INFO_UPDATED,
1019
- {info: locusInfo.parsedLocus.info, self},
1379
+ {info: locusInfo.parsedLocus.info, self},
1020
1380
  ];
1021
1381
 
1022
1382
  if (expected) {
@@ -1027,6 +1387,25 @@ describe('plugin-meetings', () => {
1027
1387
  locusInfo.emitScoped.resetHistory();
1028
1388
  };
1029
1389
 
1390
+ const checkMeetingInfoUpdatedCalledForRoles = (expected) => {
1391
+ const expectedArgs = [
1392
+ locusInfo.emitScoped,
1393
+ {
1394
+ file: 'locus-info',
1395
+ function: 'updateMeetingInfo',
1396
+ },
1397
+ LOCUSINFO.EVENTS.MEETING_INFO_UPDATED,
1398
+ ];
1399
+
1400
+ if (expected) {
1401
+ assert.calledWith(...expectedArgs);
1402
+ } else {
1403
+ assert.neverCalledWith(...expectedArgs);
1404
+ }
1405
+ locusInfo.emitScoped.resetHistory();
1406
+ };
1407
+
1408
+
1030
1409
  it('emits MEETING_INFO_UPDATED if the info changes', () => {
1031
1410
  const initialInfo = cloneDeep(meetingInfo);
1032
1411
 
@@ -1052,6 +1431,16 @@ describe('plugin-meetings', () => {
1052
1431
 
1053
1432
  // since the info is the same it should not call trigger the event
1054
1433
  checkMeetingInfoUpdatedCalled(false);
1434
+
1435
+ // update it with the same info, but roles changed
1436
+ const updateSelf = cloneDeep(self);
1437
+ updateSelf?.controls?.role?.roles.push({
1438
+ type: 'COHOST',
1439
+ hasRole: true,
1440
+ });
1441
+ locusInfo.updateMeetingInfo(newInfo, updateSelf);
1442
+ // since the info is the same but roles changed, it should call trigger the event
1443
+ checkMeetingInfoUpdatedCalledForRoles(true);
1055
1444
  });
1056
1445
 
1057
1446
  it('gets roles from self if available', () => {
@@ -1157,6 +1546,7 @@ describe('plugin-meetings', () => {
1157
1546
  fakeLocus = {
1158
1547
  meeting: true,
1159
1548
  participants: true,
1549
+ url: 'newLocusUrl',
1160
1550
  };
1161
1551
  });
1162
1552
 
@@ -1205,8 +1595,8 @@ describe('plugin-meetings', () => {
1205
1595
  const newLocus = {
1206
1596
  self: {
1207
1597
  reason: 'MOVED',
1208
- state: 'LEFT'
1209
- }
1598
+ state: 'LEFT',
1599
+ },
1210
1600
  };
1211
1601
 
1212
1602
  locusInfo.updateControls = sinon.stub();
@@ -1299,12 +1689,18 @@ describe('plugin-meetings', () => {
1299
1689
  locusInfo: {
1300
1690
  onFullLocus: sandbox.stub(),
1301
1691
  },
1692
+ locusUrl: 'oldLocusUrl',
1302
1693
  };
1303
1694
 
1304
1695
  locusInfo.locusParser.resume = sandbox.stub();
1305
1696
  locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
1306
1697
 
1307
- assert.calledOnce(meeting.meetingRequest.getFullLocus);
1698
+ assert.calledOnceWithExactly(meeting.meetingRequest.getFullLocus,
1699
+ {
1700
+ desync: true,
1701
+ locusUrl: 'newLocusUrl',
1702
+ }
1703
+ );
1308
1704
  });
1309
1705
 
1310
1706
  it('getFullLocus handles DESYNC action correctly', () => {
@@ -1329,6 +1725,187 @@ describe('plugin-meetings', () => {
1329
1725
  assert.calledOnce(locusInfo.locusParser.resume);
1330
1726
  });
1331
1727
  });
1728
+
1729
+ it('onDeltaLocus handle delta data', () => {
1730
+ fakeLocus.participants = {};
1731
+ const fakeBreakout = {
1732
+ sessionId: 'sessionId',
1733
+ groupId: 'groupId',
1734
+ };
1735
+
1736
+ fakeLocus.controls = {
1737
+ breakout: fakeBreakout
1738
+ };
1739
+ locusInfo.controls = {
1740
+ breakout: {
1741
+ sessionId: 'sessionId',
1742
+ groupId: 'groupId',
1743
+ }
1744
+ }
1745
+ locusInfo.updateParticipants = sinon.stub();
1746
+ locusInfo.onDeltaLocus(fakeLocus);
1747
+ assert.calledWith(locusInfo.updateParticipants, {}, false);
1748
+
1749
+ fakeLocus.controls.breakout.sessionId = 'sessionId2';
1750
+ locusInfo.onDeltaLocus(fakeLocus);
1751
+ assert.calledWith(locusInfo.updateParticipants, {}, true);
1752
+ });
1753
+ });
1754
+
1755
+ describe('#updateLocusCache', () => {
1756
+ it('cache it if income locus is main session locus', () => {
1757
+ const locus = {url: 'url'};
1758
+ locusInfo.mainSessionLocusCache = null;
1759
+ locusInfo.updateLocusCache(locus);
1760
+
1761
+ assert.deepEqual(locusInfo.mainSessionLocusCache, locus);
1762
+ });
1763
+
1764
+ it('not cache it if income locus is breakout session locus', () => {
1765
+ const locus = {url: 'url', controls: {breakout: {sessionType: 'BREAKOUT'}}};
1766
+ locusInfo.mainSessionLocusCache = null;
1767
+ locusInfo.updateLocusCache(locus);
1768
+
1769
+ assert.isNull(locusInfo.mainSessionLocusCache);
1770
+ });
1771
+ });
1772
+
1773
+ describe('#getTheLocusToUpdate', () => {
1774
+ it('return the cache locus if return to main session', () => {
1775
+ locusInfo.mainSessionLocusCache = {url: 'url'};
1776
+ locusInfo.controls = {
1777
+ breakout: {
1778
+ sessionType: 'BREAKOUT'
1779
+ }
1780
+ }
1781
+ const newLocus = {
1782
+ controls: {
1783
+ breakout: {
1784
+ sessionType: 'MAIN',
1785
+ },
1786
+ },
1787
+ };
1788
+
1789
+ assert.deepEqual(locusInfo.getTheLocusToUpdate(newLocus), {url: 'url'});
1790
+ });
1791
+
1792
+ it('return the new locus if return to main session but no cache', () => {
1793
+ locusInfo.mainSessionLocusCache = null;
1794
+ locusInfo.controls = {
1795
+ breakout: {
1796
+ sessionType: 'BREAKOUT'
1797
+ }
1798
+ }
1799
+ const newLocus = {
1800
+ controls: {
1801
+ breakout: {
1802
+ sessionType: 'MAIN',
1803
+ },
1804
+ },
1805
+ };
1806
+
1807
+ assert.deepEqual(locusInfo.getTheLocusToUpdate(newLocus), newLocus);
1808
+ });
1809
+
1810
+ it('return the new locus if not return to main session', () => {
1811
+ locusInfo.mainSessionLocusCache = {url: 'url'};
1812
+ locusInfo.controls = {
1813
+ breakout: {
1814
+ sessionType: 'MAIN'
1815
+ }
1816
+ }
1817
+ const newLocus = {
1818
+ controls: {
1819
+ breakout: {
1820
+ sessionType: 'BREAKOUT',
1821
+ },
1822
+ },
1823
+ };
1824
+
1825
+ assert.deepEqual(locusInfo.getTheLocusToUpdate(newLocus), newLocus);
1826
+ });
1827
+ });
1828
+
1829
+ describe('#mergeParticipants', () => {
1830
+ let participants;
1831
+ let sourceParticipants;
1832
+ beforeEach(() => {
1833
+ participants = [{id: '111', status: 'JOINED'}, {id: '222'}];
1834
+ sourceParticipants = [{id: '111', status: 'LEFT'}, {id: '333'}];
1835
+ });
1836
+
1837
+ it('merge the participants, replace it by id if exist in old array', () => {
1838
+ const result = locusInfo.mergeParticipants(participants, sourceParticipants);
1839
+ assert.deepEqual(result, [{id: '111', status: 'LEFT'}, {id: '222'}, {id: '333'}]);
1840
+ });
1841
+
1842
+ it('return new participants if previous participants is empty', () => {
1843
+ const result = locusInfo.mergeParticipants([], sourceParticipants);
1844
+ assert.deepEqual(result, sourceParticipants);
1845
+ });
1846
+
1847
+ it('return new participants if previous participants is null/undefined', () => {
1848
+ let result = locusInfo.mergeParticipants(null, sourceParticipants);
1849
+ assert.deepEqual(result, sourceParticipants);
1850
+
1851
+ result = locusInfo.mergeParticipants(undefined, sourceParticipants);
1852
+ assert.deepEqual(result, sourceParticipants);
1853
+ });
1854
+
1855
+ it('return previous participants if new participants is empty', () => {
1856
+ const result = locusInfo.mergeParticipants(participants, []);
1857
+ assert.deepEqual(result, participants);
1858
+ });
1859
+
1860
+ it('return previous participants if new participants is null/undefined', () => {
1861
+ let result = locusInfo.mergeParticipants(participants, null);
1862
+ assert.deepEqual(result, participants);
1863
+
1864
+ result = locusInfo.mergeParticipants(participants, undefined);
1865
+ assert.deepEqual(result, participants);
1866
+ });
1867
+ });
1868
+
1869
+ describe('#updateMainSessionLocusCache', () => {
1870
+ let cachedLocus;
1871
+ let newLocus;
1872
+ beforeEach(() => {
1873
+ cachedLocus = {controls: {}, participants: [], info: {webExMeetingId: 'testId1', topic: 'test'}};
1874
+ newLocus = {self: {}, participants: [{id: '111'}], info: {testId: 'testId2', webExMeetingName: 'hello'}};
1875
+ });
1876
+ it('shallow merge new locus into cache', () => {
1877
+ locusInfo.mainSessionLocusCache = cachedLocus;
1878
+ locusInfo.updateMainSessionLocusCache(newLocus);
1879
+
1880
+ assert.deepEqual(locusInfo.mainSessionLocusCache, {
1881
+ controls: {},
1882
+ participants: [{id: '111'}],
1883
+ info: {testId: 'testId2', webExMeetingName: 'hello'},
1884
+ self: {},
1885
+ });
1886
+ });
1887
+
1888
+ it('cache new locus if no cache before', () => {
1889
+ locusInfo.mainSessionLocusCache = null;
1890
+ locusInfo.updateMainSessionLocusCache(newLocus);
1891
+
1892
+ assert.deepEqual(locusInfo.mainSessionLocusCache, newLocus);
1893
+ });
1894
+
1895
+ it('do nothing if new locus is null', () => {
1896
+ locusInfo.mainSessionLocusCache = cachedLocus;
1897
+ locusInfo.updateMainSessionLocusCache(null);
1898
+
1899
+ assert.deepEqual(locusInfo.mainSessionLocusCache, cachedLocus);
1900
+ });
1901
+ });
1902
+
1903
+ describe('#clearMainSessionLocusCache', () => {
1904
+ it('clear main session locus cache', () => {
1905
+ locusInfo.mainSessionLocusCache = {controls: {}};
1906
+ locusInfo.clearMainSessionLocusCache();
1907
+ assert.isNull(locusInfo.mainSessionLocusCache);
1908
+ })
1332
1909
  });
1333
1910
 
1334
1911
  describe('#handleOneonOneEvent', () => {
@@ -1371,5 +1948,113 @@ describe('plugin-meetings', () => {
1371
1948
  );
1372
1949
  });
1373
1950
  });
1951
+
1952
+ describe('#isMeetingActive', () => {
1953
+ it('sends client event correctly for state = inactive', () => {
1954
+ locusInfo.parsedLocus = {
1955
+ fullState: {
1956
+ type: _CALL_,
1957
+ },
1958
+ };
1959
+
1960
+ locusInfo.fullState = {
1961
+ state: LOCUS.STATE.INACTIVE,
1962
+ };
1963
+
1964
+ locusInfo.isMeetingActive();
1965
+
1966
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
1967
+ name: 'client.call.remote-ended',
1968
+ options: {
1969
+ meetingId: locusInfo.meetingId,
1970
+ },
1971
+ });
1972
+ });
1973
+
1974
+ it('sends client event correctly for state = PARTNER_LEFT', () => {
1975
+ locusInfo.getLocusPartner = sinon.stub().returns({state: MEETING_STATE.STATES.LEFT})
1976
+ locusInfo.parsedLocus = {
1977
+ fullState: {
1978
+ type: _CALL_,
1979
+ },
1980
+ self: {
1981
+ state: MEETING_STATE.STATES.DECLINED,
1982
+ },
1983
+ };
1984
+ locusInfo.isMeetingActive();
1985
+
1986
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
1987
+ name: 'client.call.remote-ended',
1988
+ options: {
1989
+ meetingId: locusInfo.meetingId,
1990
+ },
1991
+ });
1992
+ });
1993
+
1994
+ it('sends client event correctly for state = SELF_LEFT', () => {
1995
+ locusInfo.getLocusPartner = sinon.stub().returns({state: MEETING_STATE.STATES.LEFT})
1996
+ locusInfo.parsedLocus = {
1997
+ fullState: {
1998
+ type: _CALL_,
1999
+ },
2000
+ self: {
2001
+ state: MEETING_STATE.STATES.LEFT,
2002
+ },
2003
+ };
2004
+
2005
+ locusInfo.isMeetingActive();
2006
+
2007
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
2008
+ name: 'client.call.remote-ended',
2009
+ options: {
2010
+ meetingId: locusInfo.meetingId,
2011
+ },
2012
+ });
2013
+ });
2014
+
2015
+ it('sends client event correctly for state = MEETING_INACTIVE_TERMINATING', () => {
2016
+ locusInfo.getLocusPartner = sinon.stub().returns({state: MEETING_STATE.STATES.LEFT})
2017
+ locusInfo.parsedLocus = {
2018
+ fullState: {
2019
+ type: _MEETING_,
2020
+ },
2021
+ };
2022
+
2023
+ locusInfo.fullState = {
2024
+ state: LOCUS.STATE.INACTIVE,
2025
+ };
2026
+
2027
+ locusInfo.isMeetingActive();
2028
+
2029
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
2030
+ name: 'client.call.remote-ended',
2031
+ options: {
2032
+ meetingId: locusInfo.meetingId,
2033
+ },
2034
+ });
2035
+ });
2036
+
2037
+ it('sends client event correctly for state = FULLSTATE_REMOVED', () => {
2038
+ locusInfo.getLocusPartner = sinon.stub().returns({state: MEETING_STATE.STATES.LEFT})
2039
+ locusInfo.parsedLocus = {
2040
+ fullState: {
2041
+ type: _MEETING_,
2042
+ },
2043
+ };
2044
+
2045
+ locusInfo.fullState = {
2046
+ removed: true
2047
+ };
2048
+
2049
+ locusInfo.isMeetingActive();
2050
+
2051
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
2052
+ name: 'client.call.remote-ended',
2053
+ options: {
2054
+ meetingId: locusInfo.meetingId,
2055
+ },
2056
+ });
2057
+ });
2058
+ });
1374
2059
  });
1375
2060
  });