@webex/plugin-meetings 3.0.0-beta.1 → 3.0.0-beta.104

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 (548) hide show
  1. package/UPGRADING.md +9 -9
  2. package/browsers.js +19 -24
  3. package/dist/annotation/annotation.types.js +7 -0
  4. package/dist/annotation/annotation.types.js.map +1 -0
  5. package/dist/annotation/constants.js +48 -0
  6. package/dist/annotation/constants.js.map +1 -0
  7. package/dist/annotation/index.js +357 -0
  8. package/dist/annotation/index.js.map +1 -0
  9. package/dist/breakouts/breakout.js +176 -0
  10. package/dist/breakouts/breakout.js.map +1 -0
  11. package/dist/breakouts/collection.js +23 -0
  12. package/dist/breakouts/collection.js.map +1 -0
  13. package/dist/breakouts/edit-lock-error.js +52 -0
  14. package/dist/breakouts/edit-lock-error.js.map +1 -0
  15. package/dist/breakouts/events.js +43 -0
  16. package/dist/breakouts/events.js.map +1 -0
  17. package/dist/breakouts/index.js +919 -0
  18. package/dist/breakouts/index.js.map +1 -0
  19. package/dist/breakouts/request.js +78 -0
  20. package/dist/breakouts/request.js.map +1 -0
  21. package/dist/breakouts/utils.js +67 -0
  22. package/dist/breakouts/utils.js.map +1 -0
  23. package/dist/common/browser-detection.js +1 -20
  24. package/dist/common/browser-detection.js.map +1 -1
  25. package/dist/common/collection.js +5 -20
  26. package/dist/common/collection.js.map +1 -1
  27. package/dist/common/config.js +0 -7
  28. package/dist/common/config.js.map +1 -1
  29. package/dist/common/errors/captcha-error.js +10 -24
  30. package/dist/common/errors/captcha-error.js.map +1 -1
  31. package/dist/common/errors/intent-to-join.js +11 -24
  32. package/dist/common/errors/intent-to-join.js.map +1 -1
  33. package/dist/common/errors/join-meeting.js +12 -25
  34. package/dist/common/errors/join-meeting.js.map +1 -1
  35. package/dist/common/errors/media.js +10 -24
  36. package/dist/common/errors/media.js.map +1 -1
  37. package/dist/common/errors/parameter.js +5 -33
  38. package/dist/common/errors/parameter.js.map +1 -1
  39. package/dist/common/errors/password-error.js +10 -24
  40. package/dist/common/errors/password-error.js.map +1 -1
  41. package/dist/common/errors/permission.js +9 -23
  42. package/dist/common/errors/permission.js.map +1 -1
  43. package/dist/common/errors/reconnection-in-progress.js +0 -17
  44. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  45. package/dist/common/errors/reconnection.js +10 -24
  46. package/dist/common/errors/reconnection.js.map +1 -1
  47. package/dist/common/errors/stats.js +10 -24
  48. package/dist/common/errors/stats.js.map +1 -1
  49. package/dist/common/errors/webex-errors.js +10 -69
  50. package/dist/common/errors/webex-errors.js.map +1 -1
  51. package/dist/common/errors/webex-meetings-error.js +5 -25
  52. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  53. package/dist/common/events/events-scope.js +0 -22
  54. package/dist/common/events/events-scope.js.map +1 -1
  55. package/dist/common/events/events.js +0 -23
  56. package/dist/common/events/events.js.map +1 -1
  57. package/dist/common/events/trigger-proxy.js +0 -12
  58. package/dist/common/events/trigger-proxy.js.map +1 -1
  59. package/dist/common/events/util.js +0 -15
  60. package/dist/common/events/util.js.map +1 -1
  61. package/dist/common/logs/logger-config.js +0 -4
  62. package/dist/common/logs/logger-config.js.map +1 -1
  63. package/dist/common/logs/logger-proxy.js +1 -8
  64. package/dist/common/logs/logger-proxy.js.map +1 -1
  65. package/dist/common/logs/request.js +37 -60
  66. package/dist/common/logs/request.js.map +1 -1
  67. package/dist/common/queue.js +4 -14
  68. package/dist/common/queue.js.map +1 -1
  69. package/dist/config.js +7 -6
  70. package/dist/config.js.map +1 -1
  71. package/dist/constants.js +184 -122
  72. package/dist/constants.js.map +1 -1
  73. package/dist/controls-options-manager/constants.js +14 -0
  74. package/dist/controls-options-manager/constants.js.map +1 -0
  75. package/dist/controls-options-manager/enums.js +25 -0
  76. package/dist/controls-options-manager/enums.js.map +1 -0
  77. package/dist/controls-options-manager/index.js +297 -0
  78. package/dist/controls-options-manager/index.js.map +1 -0
  79. package/dist/controls-options-manager/types.js +7 -0
  80. package/dist/controls-options-manager/types.js.map +1 -0
  81. package/dist/controls-options-manager/util.js +250 -0
  82. package/dist/controls-options-manager/util.js.map +1 -0
  83. package/dist/index.js +72 -17
  84. package/dist/index.js.map +1 -1
  85. package/dist/locus-info/controlsUtils.js +56 -29
  86. package/dist/locus-info/controlsUtils.js.map +1 -1
  87. package/dist/locus-info/embeddedAppsUtils.js +3 -26
  88. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  89. package/dist/locus-info/fullState.js +0 -15
  90. package/dist/locus-info/fullState.js.map +1 -1
  91. package/dist/locus-info/hostUtils.js +4 -12
  92. package/dist/locus-info/hostUtils.js.map +1 -1
  93. package/dist/locus-info/index.js +362 -208
  94. package/dist/locus-info/index.js.map +1 -1
  95. package/dist/locus-info/infoUtils.js +3 -37
  96. package/dist/locus-info/infoUtils.js.map +1 -1
  97. package/dist/locus-info/mediaSharesUtils.js +12 -38
  98. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  99. package/dist/locus-info/parser.js +92 -118
  100. package/dist/locus-info/parser.js.map +1 -1
  101. package/dist/locus-info/selfUtils.js +99 -91
  102. package/dist/locus-info/selfUtils.js.map +1 -1
  103. package/dist/media/index.js +113 -337
  104. package/dist/media/index.js.map +1 -1
  105. package/dist/media/properties.js +96 -135
  106. package/dist/media/properties.js.map +1 -1
  107. package/dist/media/util.js +1 -35
  108. package/dist/media/util.js.map +1 -1
  109. package/dist/mediaQualityMetrics/config.js +505 -495
  110. package/dist/mediaQualityMetrics/config.js.map +1 -1
  111. package/dist/meeting/in-meeting-actions.js +59 -14
  112. package/dist/meeting/in-meeting-actions.js.map +1 -1
  113. package/dist/meeting/index.js +2909 -2398
  114. package/dist/meeting/index.js.map +1 -1
  115. package/dist/meeting/muteState.js +257 -112
  116. package/dist/meeting/muteState.js.map +1 -1
  117. package/dist/meeting/request.js +330 -264
  118. package/dist/meeting/request.js.map +1 -1
  119. package/dist/meeting/request.type.js +7 -0
  120. package/dist/meeting/request.type.js.map +1 -0
  121. package/dist/meeting/state.js +21 -31
  122. package/dist/meeting/state.js.map +1 -1
  123. package/dist/meeting/util.js +63 -261
  124. package/dist/meeting/util.js.map +1 -1
  125. package/dist/meeting-info/collection.js +6 -25
  126. package/dist/meeting-info/collection.js.map +1 -1
  127. package/dist/meeting-info/index.js +14 -32
  128. package/dist/meeting-info/index.js.map +1 -1
  129. package/dist/meeting-info/meeting-info-v2.js +273 -280
  130. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  131. package/dist/meeting-info/request.js +3 -15
  132. package/dist/meeting-info/request.js.map +1 -1
  133. package/dist/meeting-info/util.js +98 -183
  134. package/dist/meeting-info/util.js.map +1 -1
  135. package/dist/meeting-info/utilv2.js +155 -232
  136. package/dist/meeting-info/utilv2.js.map +1 -1
  137. package/dist/meetings/collection.js +26 -19
  138. package/dist/meetings/collection.js.map +1 -1
  139. package/dist/meetings/index.js +741 -548
  140. package/dist/meetings/index.js.map +1 -1
  141. package/dist/meetings/request.js +26 -41
  142. package/dist/meetings/request.js.map +1 -1
  143. package/dist/meetings/util.js +194 -149
  144. package/dist/meetings/util.js.map +1 -1
  145. package/dist/member/index.js +100 -85
  146. package/dist/member/index.js.map +1 -1
  147. package/dist/member/types.js +15 -0
  148. package/dist/member/types.js.map +1 -0
  149. package/dist/member/util.js +90 -68
  150. package/dist/member/util.js.map +1 -1
  151. package/dist/members/collection.js +13 -12
  152. package/dist/members/collection.js.map +1 -1
  153. package/dist/members/index.js +227 -188
  154. package/dist/members/index.js.map +1 -1
  155. package/dist/members/request.js +54 -39
  156. package/dist/members/request.js.map +1 -1
  157. package/dist/members/types.js +15 -0
  158. package/dist/members/types.js.map +1 -0
  159. package/dist/members/util.js +107 -44
  160. package/dist/members/util.js.map +1 -1
  161. package/dist/metrics/config.js +5 -14
  162. package/dist/metrics/config.js.map +1 -1
  163. package/dist/metrics/constants.js +3 -7
  164. package/dist/metrics/constants.js.map +1 -1
  165. package/dist/metrics/index.js +67 -159
  166. package/dist/metrics/index.js.map +1 -1
  167. package/dist/multistream/mediaRequestManager.js +250 -0
  168. package/dist/multistream/mediaRequestManager.js.map +1 -0
  169. package/dist/multistream/receiveSlot.js +202 -0
  170. package/dist/multistream/receiveSlot.js.map +1 -0
  171. package/dist/multistream/receiveSlotManager.js +176 -0
  172. package/dist/multistream/receiveSlotManager.js.map +1 -0
  173. package/dist/multistream/remoteMedia.js +270 -0
  174. package/dist/multistream/remoteMedia.js.map +1 -0
  175. package/dist/multistream/remoteMediaGroup.js +209 -0
  176. package/dist/multistream/remoteMediaGroup.js.map +1 -0
  177. package/dist/multistream/remoteMediaManager.js +1137 -0
  178. package/dist/multistream/remoteMediaManager.js.map +1 -0
  179. package/dist/networkQualityMonitor/index.js +40 -59
  180. package/dist/networkQualityMonitor/index.js.map +1 -1
  181. package/dist/personal-meeting-room/index.js +21 -45
  182. package/dist/personal-meeting-room/index.js.map +1 -1
  183. package/dist/personal-meeting-room/request.js +1 -31
  184. package/dist/personal-meeting-room/request.js.map +1 -1
  185. package/dist/personal-meeting-room/util.js +0 -13
  186. package/dist/personal-meeting-room/util.js.map +1 -1
  187. package/dist/reachability/index.js +192 -191
  188. package/dist/reachability/index.js.map +1 -1
  189. package/dist/reachability/request.js +15 -23
  190. package/dist/reachability/request.js.map +1 -1
  191. package/dist/reactions/constants.js +13 -0
  192. package/dist/reactions/constants.js.map +1 -0
  193. package/dist/reactions/reactions.js +109 -0
  194. package/dist/reactions/reactions.js.map +1 -0
  195. package/dist/reactions/reactions.type.js +36 -0
  196. package/dist/reactions/reactions.type.js.map +1 -0
  197. package/dist/reconnection-manager/index.js +386 -527
  198. package/dist/reconnection-manager/index.js.map +1 -1
  199. package/dist/recording-controller/enums.js +17 -0
  200. package/dist/recording-controller/enums.js.map +1 -0
  201. package/dist/recording-controller/index.js +343 -0
  202. package/dist/recording-controller/index.js.map +1 -0
  203. package/dist/recording-controller/util.js +63 -0
  204. package/dist/recording-controller/util.js.map +1 -0
  205. package/dist/roap/index.js +84 -286
  206. package/dist/roap/index.js.map +1 -1
  207. package/dist/roap/request.js +138 -238
  208. package/dist/roap/request.js.map +1 -1
  209. package/dist/roap/turnDiscovery.js +164 -102
  210. package/dist/roap/turnDiscovery.js.map +1 -1
  211. package/dist/statsAnalyzer/global.js +1 -93
  212. package/dist/statsAnalyzer/global.js.map +1 -1
  213. package/dist/statsAnalyzer/index.js +399 -470
  214. package/dist/statsAnalyzer/index.js.map +1 -1
  215. package/dist/statsAnalyzer/mqaUtil.js +143 -87
  216. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  217. package/dist/transcription/index.js +22 -47
  218. package/dist/transcription/index.js.map +1 -1
  219. package/dist/types/annotation/annotation.types.d.ts +34 -0
  220. package/dist/types/annotation/constants.d.ts +31 -0
  221. package/dist/types/annotation/index.d.ts +124 -0
  222. package/dist/types/breakouts/breakout.d.ts +8 -0
  223. package/dist/types/breakouts/collection.d.ts +5 -0
  224. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  225. package/dist/types/breakouts/events.d.ts +2 -0
  226. package/dist/types/breakouts/index.d.ts +5 -0
  227. package/dist/types/breakouts/request.d.ts +22 -0
  228. package/dist/types/breakouts/utils.d.ts +15 -0
  229. package/dist/types/common/browser-detection.d.ts +9 -0
  230. package/dist/types/common/collection.d.ts +48 -0
  231. package/dist/types/common/config.d.ts +2 -0
  232. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  233. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  234. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  235. package/dist/types/common/errors/media.d.ts +15 -0
  236. package/dist/types/common/errors/parameter.d.ts +15 -0
  237. package/dist/types/common/errors/password-error.d.ts +15 -0
  238. package/dist/types/common/errors/permission.d.ts +14 -0
  239. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  240. package/dist/types/common/errors/reconnection.d.ts +15 -0
  241. package/dist/types/common/errors/stats.d.ts +15 -0
  242. package/dist/types/common/errors/webex-errors.d.ts +69 -0
  243. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  244. package/dist/types/common/events/events-scope.d.ts +17 -0
  245. package/dist/types/common/events/events.d.ts +12 -0
  246. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  247. package/dist/types/common/events/util.d.ts +2 -0
  248. package/dist/types/common/logs/logger-config.d.ts +2 -0
  249. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  250. package/dist/types/common/logs/request.d.ts +34 -0
  251. package/dist/types/common/queue.d.ts +32 -0
  252. package/dist/types/config.d.ts +78 -0
  253. package/dist/types/constants.d.ts +968 -0
  254. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  255. package/dist/types/controls-options-manager/enums.d.ts +13 -0
  256. package/dist/types/controls-options-manager/index.d.ts +136 -0
  257. package/dist/types/controls-options-manager/types.d.ts +37 -0
  258. package/dist/types/controls-options-manager/util.d.ts +1 -0
  259. package/dist/types/index.d.ts +7 -0
  260. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  261. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  262. package/dist/types/locus-info/fullState.d.ts +2 -0
  263. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  264. package/dist/types/locus-info/index.d.ts +315 -0
  265. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  266. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  267. package/dist/types/locus-info/parser.d.ts +212 -0
  268. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  269. package/dist/types/media/index.d.ts +34 -0
  270. package/dist/types/media/properties.d.ts +108 -0
  271. package/dist/types/media/util.d.ts +2 -0
  272. package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
  273. package/dist/types/meeting/in-meeting-actions.d.ts +129 -0
  274. package/dist/types/meeting/index.d.ts +1748 -0
  275. package/dist/types/meeting/muteState.d.ts +185 -0
  276. package/dist/types/meeting/request.d.ts +275 -0
  277. package/dist/types/meeting/request.type.d.ts +11 -0
  278. package/dist/types/meeting/state.d.ts +9 -0
  279. package/dist/types/meeting/util.d.ts +2 -0
  280. package/dist/types/meeting-info/collection.d.ts +20 -0
  281. package/dist/types/meeting-info/index.d.ts +57 -0
  282. package/dist/types/meeting-info/meeting-info-v2.d.ts +112 -0
  283. package/dist/types/meeting-info/request.d.ts +22 -0
  284. package/dist/types/meeting-info/util.d.ts +2 -0
  285. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  286. package/dist/types/meetings/collection.d.ts +31 -0
  287. package/dist/types/meetings/index.d.ts +345 -0
  288. package/dist/types/meetings/request.d.ts +27 -0
  289. package/dist/types/meetings/util.d.ts +18 -0
  290. package/dist/types/member/index.d.ts +156 -0
  291. package/dist/types/member/types.d.ts +21 -0
  292. package/dist/types/member/util.d.ts +2 -0
  293. package/dist/types/members/collection.d.ts +29 -0
  294. package/dist/types/members/index.d.ts +353 -0
  295. package/dist/types/members/request.d.ts +69 -0
  296. package/dist/types/members/types.d.ts +24 -0
  297. package/dist/types/members/util.d.ts +2 -0
  298. package/dist/types/metrics/config.d.ts +172 -0
  299. package/dist/types/metrics/constants.d.ts +54 -0
  300. package/dist/types/metrics/index.d.ts +152 -0
  301. package/dist/types/multistream/mediaRequestManager.d.ts +101 -0
  302. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  303. package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
  304. package/dist/types/multistream/remoteMedia.d.ts +72 -0
  305. package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
  306. package/dist/types/multistream/remoteMediaManager.d.ts +263 -0
  307. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  308. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  309. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  310. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  311. package/dist/types/reachability/index.d.ts +152 -0
  312. package/dist/types/reachability/request.d.ts +37 -0
  313. package/dist/types/reactions/constants.d.ts +3 -0
  314. package/dist/types/reactions/reactions.d.ts +4 -0
  315. package/dist/types/reactions/reactions.type.d.ts +52 -0
  316. package/dist/types/reconnection-manager/index.d.ts +126 -0
  317. package/dist/types/recording-controller/enums.d.ts +7 -0
  318. package/dist/types/recording-controller/index.d.ts +193 -0
  319. package/dist/types/recording-controller/util.d.ts +13 -0
  320. package/dist/types/roap/index.d.ts +77 -0
  321. package/dist/types/roap/request.d.ts +38 -0
  322. package/dist/types/roap/turnDiscovery.d.ts +88 -0
  323. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  324. package/dist/types/statsAnalyzer/index.d.ts +200 -0
  325. package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
  326. package/dist/types/transcription/index.d.ts +64 -0
  327. package/internal-README.md +7 -6
  328. package/package.json +29 -21
  329. package/src/annotation/annotation.types.ts +41 -0
  330. package/src/annotation/constants.ts +36 -0
  331. package/src/annotation/index.ts +339 -0
  332. package/src/breakouts/README.md +219 -0
  333. package/src/breakouts/breakout.ts +141 -0
  334. package/src/breakouts/collection.ts +19 -0
  335. package/src/breakouts/edit-lock-error.ts +25 -0
  336. package/src/breakouts/events.ts +37 -0
  337. package/src/breakouts/index.ts +823 -0
  338. package/src/breakouts/request.ts +55 -0
  339. package/src/breakouts/utils.ts +57 -0
  340. package/src/common/{browser-detection.js → browser-detection.ts} +9 -6
  341. package/src/common/collection.ts +9 -7
  342. package/src/common/{config.js → config.ts} +1 -1
  343. package/src/common/errors/{captcha-error.js → captcha-error.ts} +11 -7
  344. package/src/common/errors/{intent-to-join.js → intent-to-join.ts} +12 -7
  345. package/src/common/errors/{join-meeting.js → join-meeting.ts} +17 -8
  346. package/src/common/errors/{media.js → media.ts} +11 -7
  347. package/src/common/errors/parameter.ts +11 -7
  348. package/src/common/errors/{password-error.js → password-error.ts} +11 -7
  349. package/src/common/errors/{permission.js → permission.ts} +10 -6
  350. package/src/common/errors/{reconnection.js → reconnection.ts} +11 -7
  351. package/src/common/errors/{stats.js → stats.ts} +11 -7
  352. package/src/common/errors/{webex-errors.js → webex-errors.ts} +8 -25
  353. package/src/common/errors/{webex-meetings-error.js → webex-meetings-error.ts} +4 -2
  354. package/src/common/events/{events-scope.js → events-scope.ts} +6 -2
  355. package/src/common/events/{events.js → events.ts} +5 -1
  356. package/src/common/events/{trigger-proxy.js → trigger-proxy.ts} +9 -5
  357. package/src/common/events/{util.js → util.ts} +2 -3
  358. package/src/common/logs/{logger-config.js → logger-config.ts} +1 -2
  359. package/src/common/logs/logger-proxy.ts +44 -0
  360. package/src/common/logs/{request.js → request.ts} +22 -9
  361. package/src/common/queue.ts +1 -2
  362. package/src/{config.js → config.ts} +18 -12
  363. package/src/constants.ts +256 -183
  364. package/src/controls-options-manager/constants.ts +5 -0
  365. package/src/controls-options-manager/enums.ts +16 -0
  366. package/src/controls-options-manager/index.ts +278 -0
  367. package/src/controls-options-manager/types.ts +49 -0
  368. package/src/controls-options-manager/util.ts +229 -0
  369. package/src/index.ts +33 -0
  370. package/src/locus-info/controlsUtils.ts +169 -0
  371. package/src/locus-info/{embeddedAppsUtils.js → embeddedAppsUtils.ts} +5 -6
  372. package/src/locus-info/{fullState.js → fullState.ts} +16 -12
  373. package/src/locus-info/{hostUtils.js → hostUtils.ts} +9 -8
  374. package/src/locus-info/{index.js → index.ts} +331 -80
  375. package/src/locus-info/{infoUtils.js → infoUtils.ts} +19 -8
  376. package/src/locus-info/{mediaSharesUtils.js → mediaSharesUtils.ts} +17 -17
  377. package/src/locus-info/{parser.js → parser.ts} +67 -79
  378. package/src/locus-info/{selfUtils.js → selfUtils.ts} +196 -67
  379. package/src/media/index.ts +488 -0
  380. package/src/media/{properties.js → properties.ts} +67 -54
  381. package/src/media/util.ts +16 -0
  382. package/src/mediaQualityMetrics/config.ts +384 -0
  383. package/src/meeting/in-meeting-actions.ts +123 -3
  384. package/src/meeting/{index.js → index.ts} +3334 -1775
  385. package/src/meeting/muteState.ts +526 -0
  386. package/src/meeting/{request.js → request.ts} +350 -142
  387. package/src/meeting/request.type.ts +13 -0
  388. package/src/meeting/{state.js → state.ts} +50 -35
  389. package/src/meeting/{util.js → util.ts} +126 -159
  390. package/src/meeting-info/{collection.js → collection.ts} +6 -2
  391. package/src/meeting-info/{index.js → index.ts} +42 -36
  392. package/src/meeting-info/meeting-info-v2.ts +345 -0
  393. package/src/meeting-info/{request.js → request.ts} +14 -4
  394. package/src/meeting-info/{util.js → util.ts} +60 -51
  395. package/src/meeting-info/{utilv2.js → utilv2.ts} +76 -60
  396. package/src/meetings/{collection.js → collection.ts} +26 -3
  397. package/src/meetings/index.ts +1394 -0
  398. package/src/meetings/{request.js → request.ts} +34 -25
  399. package/src/meetings/util.ts +288 -0
  400. package/src/member/{index.js → index.ts} +124 -56
  401. package/src/member/types.ts +24 -0
  402. package/src/member/{util.js → util.ts} +105 -25
  403. package/src/members/{collection.js → collection.ts} +10 -2
  404. package/src/members/{index.js → index.ts} +359 -139
  405. package/src/members/request.ts +215 -0
  406. package/src/members/types.ts +28 -0
  407. package/src/members/{util.js → util.ts} +145 -54
  408. package/src/metrics/{config.js → config.ts} +256 -92
  409. package/src/metrics/{constants.js → constants.ts} +1 -6
  410. package/src/metrics/{index.js → index.ts} +116 -97
  411. package/src/multistream/mediaRequestManager.ts +324 -0
  412. package/src/multistream/receiveSlot.ts +184 -0
  413. package/src/multistream/receiveSlotManager.ts +166 -0
  414. package/src/multistream/remoteMedia.ts +254 -0
  415. package/src/multistream/remoteMediaGroup.ts +225 -0
  416. package/src/multistream/remoteMediaManager.ts +1075 -0
  417. package/src/networkQualityMonitor/{index.js → index.ts} +41 -29
  418. package/src/personal-meeting-room/{index.js → index.ts} +28 -19
  419. package/src/personal-meeting-room/{request.js → request.ts} +13 -4
  420. package/src/personal-meeting-room/{util.js → util.ts} +4 -4
  421. package/src/reachability/{index.js → index.ts} +157 -94
  422. package/src/reachability/request.ts +46 -35
  423. package/src/reactions/constants.ts +4 -0
  424. package/src/reactions/reactions.ts +104 -0
  425. package/src/reactions/reactions.type.ts +62 -0
  426. package/src/reconnection-manager/{index.js → index.ts} +261 -163
  427. package/src/recording-controller/enums.ts +8 -0
  428. package/src/recording-controller/index.ts +315 -0
  429. package/src/recording-controller/util.ts +58 -0
  430. package/src/roap/index.ts +241 -0
  431. package/src/roap/request.ts +172 -0
  432. package/src/roap/turnDiscovery.ts +127 -53
  433. package/src/statsAnalyzer/global.ts +37 -0
  434. package/src/statsAnalyzer/index.ts +1273 -0
  435. package/src/statsAnalyzer/mqaUtil.ts +291 -0
  436. package/src/transcription/{index.js → index.ts} +46 -39
  437. package/test/integration/spec/converged-space-meetings.js +177 -0
  438. package/test/integration/spec/journey.js +666 -464
  439. package/test/integration/spec/space-meeting.js +321 -206
  440. package/test/integration/spec/transcription.js +7 -8
  441. package/test/unit/spec/annotation/index.ts +435 -0
  442. package/test/unit/spec/breakouts/breakout.ts +184 -0
  443. package/test/unit/spec/breakouts/collection.ts +15 -0
  444. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  445. package/test/unit/spec/breakouts/events.ts +77 -0
  446. package/test/unit/spec/breakouts/index.ts +1504 -0
  447. package/test/unit/spec/breakouts/request.ts +104 -0
  448. package/test/unit/spec/breakouts/utils.js +72 -0
  449. package/test/unit/spec/common/browser-detection.js +9 -28
  450. package/test/unit/spec/controls-options-manager/index.js +287 -0
  451. package/test/unit/spec/controls-options-manager/util.js +403 -0
  452. package/test/unit/spec/fixture/locus.js +92 -90
  453. package/test/unit/spec/locus-info/controlsUtils.js +177 -32
  454. package/test/unit/spec/locus-info/embeddedAppsUtils.js +8 -6
  455. package/test/unit/spec/locus-info/index.js +493 -3
  456. package/test/unit/spec/locus-info/infoUtils.js +41 -32
  457. package/test/unit/spec/locus-info/lib/BasicSeqCmp.json +88 -430
  458. package/test/unit/spec/locus-info/lib/SeqCmp.json +513 -685
  459. package/test/unit/spec/locus-info/parser.js +3 -9
  460. package/test/unit/spec/locus-info/selfConstant.js +110 -103
  461. package/test/unit/spec/locus-info/selfUtils.js +236 -12
  462. package/test/unit/spec/media/index.ts +303 -0
  463. package/test/unit/spec/media/properties.ts +73 -82
  464. package/test/unit/spec/meeting/in-meeting-actions.ts +58 -3
  465. package/test/unit/spec/meeting/index.js +3127 -975
  466. package/test/unit/spec/meeting/muteState.js +375 -70
  467. package/test/unit/spec/meeting/request.js +217 -43
  468. package/test/unit/spec/meeting/utils.js +205 -163
  469. package/test/unit/spec/meeting-info/meetinginfov2.js +268 -74
  470. package/test/unit/spec/meeting-info/request.js +7 -9
  471. package/test/unit/spec/meeting-info/util.js +11 -12
  472. package/test/unit/spec/meeting-info/utilv2.js +131 -74
  473. package/test/unit/spec/meetings/collection.js +15 -1
  474. package/test/unit/spec/meetings/index.js +1052 -333
  475. package/test/unit/spec/meetings/utils.js +163 -14
  476. package/test/unit/spec/member/index.js +24 -1
  477. package/test/unit/spec/member/util.js +359 -32
  478. package/test/unit/spec/members/index.js +547 -37
  479. package/test/unit/spec/members/request.js +76 -20
  480. package/test/unit/spec/members/utils.js +191 -4
  481. package/test/unit/spec/metrics/index.js +46 -20
  482. package/test/unit/spec/multistream/mediaRequestManager.ts +1060 -0
  483. package/test/unit/spec/multistream/receiveSlot.ts +163 -0
  484. package/test/unit/spec/multistream/receiveSlotManager.ts +203 -0
  485. package/test/unit/spec/multistream/remoteMedia.ts +255 -0
  486. package/test/unit/spec/multistream/remoteMediaGroup.ts +396 -0
  487. package/test/unit/spec/multistream/remoteMediaManager.ts +1793 -0
  488. package/test/unit/spec/networkQualityMonitor/index.js +24 -18
  489. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -7
  490. package/test/unit/spec/reachability/index.ts +176 -27
  491. package/test/unit/spec/reachability/request.js +66 -0
  492. package/test/unit/spec/reconnection-manager/index.js +106 -9
  493. package/test/unit/spec/recording-controller/index.js +231 -0
  494. package/test/unit/spec/recording-controller/util.js +102 -0
  495. package/test/unit/spec/roap/index.ts +78 -45
  496. package/test/unit/spec/roap/request.ts +217 -0
  497. package/test/unit/spec/roap/turnDiscovery.ts +93 -49
  498. package/test/unit/spec/stats-analyzer/index.js +118 -65
  499. package/test/utils/cmr.js +44 -42
  500. package/test/utils/constants.js +9 -0
  501. package/test/utils/integrationTestUtils.js +64 -0
  502. package/test/utils/testUtils.js +63 -99
  503. package/test/utils/webex-config.js +22 -18
  504. package/test/utils/webex-test-users.js +57 -50
  505. package/tsconfig.json +6 -0
  506. package/dist/meeting/effectsState.js +0 -327
  507. package/dist/meeting/effectsState.js.map +0 -1
  508. package/dist/peer-connection-manager/index.js +0 -794
  509. package/dist/peer-connection-manager/index.js.map +0 -1
  510. package/dist/peer-connection-manager/util.js +0 -124
  511. package/dist/peer-connection-manager/util.js.map +0 -1
  512. package/dist/roap/collection.js +0 -73
  513. package/dist/roap/collection.js.map +0 -1
  514. package/dist/roap/handler.js +0 -337
  515. package/dist/roap/handler.js.map +0 -1
  516. package/dist/roap/state.js +0 -164
  517. package/dist/roap/state.js.map +0 -1
  518. package/dist/roap/util.js +0 -102
  519. package/dist/roap/util.js.map +0 -1
  520. package/src/common/logs/logger-proxy.js +0 -33
  521. package/src/index.js +0 -15
  522. package/src/locus-info/controlsUtils.js +0 -102
  523. package/src/media/index.js +0 -593
  524. package/src/media/util.js +0 -38
  525. package/src/mediaQualityMetrics/config.js +0 -382
  526. package/src/meeting/effectsState.js +0 -205
  527. package/src/meeting/muteState.js +0 -318
  528. package/src/meeting-info/meeting-info-v2.js +0 -255
  529. package/src/meetings/index.js +0 -986
  530. package/src/meetings/util.js +0 -176
  531. package/src/members/request.js +0 -131
  532. package/src/peer-connection-manager/index.js +0 -723
  533. package/src/peer-connection-manager/util.ts +0 -117
  534. package/src/roap/collection.js +0 -63
  535. package/src/roap/handler.js +0 -252
  536. package/src/roap/index.js +0 -380
  537. package/src/roap/request.js +0 -198
  538. package/src/roap/state.js +0 -149
  539. package/src/roap/util.js +0 -93
  540. package/src/statsAnalyzer/global.js +0 -131
  541. package/src/statsAnalyzer/index.js +0 -1020
  542. package/src/statsAnalyzer/mqaUtil.js +0 -173
  543. package/test/unit/spec/meeting/effectsState.js +0 -293
  544. package/test/unit/spec/peerconnection-manager/index.js +0 -188
  545. package/test/unit/spec/peerconnection-manager/utils.js +0 -48
  546. package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -389
  547. package/test/unit/spec/roap/util.js +0 -30
  548. /package/src/common/errors/{reconnection-in-progress.js → reconnection-in-progress.ts} +0 -0
@@ -11,8 +11,8 @@ import sinon from 'sinon';
11
11
  import uuid from 'uuid';
12
12
  import StaticConfig from '@webex/plugin-meetings/src/common/config';
13
13
  import TriggerProxy from '@webex/plugin-meetings/src/common/events/trigger-proxy';
14
+ import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
14
15
  import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
15
- import MediaUtil from '@webex/plugin-meetings/src/media/util';
16
16
  import Meeting from '@webex/plugin-meetings/src/meeting';
17
17
  import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
18
18
  import Meetings from '@webex/plugin-meetings/src/meetings';
@@ -28,8 +28,12 @@ import {
28
28
  ONLINE,
29
29
  ROAP,
30
30
  LOCUSINFO,
31
- EVENT_TRIGGERS
31
+ EVENT_TRIGGERS,
32
32
  } from '../../../../src/constants';
33
+ import CaptchaError from '@webex/plugin-meetings/src/common/errors/captcha-error';
34
+ import { forEach } from 'lodash';
35
+ import PasswordError from '@webex/plugin-meetings/src/common/errors/password-error';
36
+ import PermissionError from '@webex/plugin-meetings/src/common/errors/permission';
33
37
 
34
38
  describe('plugin-meetings', () => {
35
39
  const logger = {
@@ -38,17 +42,19 @@ describe('plugin-meetings', () => {
38
42
  error: () => {},
39
43
  warn: () => {},
40
44
  trace: () => {},
41
- debug: () => {}
45
+ debug: () => {},
42
46
  };
43
47
 
44
48
  beforeEach(() => {
45
49
  StaticConfig.set({
46
50
  bandwidth: {
47
- audio: 50, video: 500
48
- }
51
+ audio: 50,
52
+ video: 500,
53
+ },
49
54
  });
50
55
  LoggerConfig.set({
51
- verboseEvents: true, enable: false
56
+ verboseEvents: true,
57
+ enable: false,
52
58
  });
53
59
  TriggerProxy.trigger = sinon.stub().returns(true);
54
60
  });
@@ -59,6 +65,7 @@ describe('plugin-meetings', () => {
59
65
  let url1;
60
66
  let test1;
61
67
  let test2;
68
+ let locusInfo;
62
69
 
63
70
  describe('meetings index', () => {
64
71
  beforeEach(() => {
@@ -68,17 +75,20 @@ describe('plugin-meetings', () => {
68
75
  uri1 = `test-${uuid.v4()}@example.com`;
69
76
  test1 = `test-${uuid.v4()}`;
70
77
  test2 = `test2-${uuid.v4()}`;
78
+ locusInfo = {
79
+ parse: sinon.stub().returns(true),
80
+ updateMainSessionLocusCache: sinon.stub(),
81
+ };
71
82
  webex = new MockWebex({
72
83
  children: {
73
84
  device: Device,
74
85
  mercury: Mercury,
75
- meetings: Meetings
76
- }
86
+ meetings: Meetings,
87
+ },
77
88
  });
78
89
 
79
-
80
90
  Object.assign(webex, {
81
- logging: logger
91
+ logging: logger,
82
92
  });
83
93
 
84
94
  Object.assign(webex.meetings.config, {
@@ -87,68 +97,74 @@ describe('plugin-meetings', () => {
87
97
  // the server supports, minimums have to be tested
88
98
  audio: 64000,
89
99
  video: 4000000,
90
- startBitrate: 2000
100
+ startBitrate: 2000,
91
101
  },
92
102
  experimental: {
93
- enableUnifiedMeetings: true
103
+ enableUnifiedMeetings: true,
94
104
  },
95
105
  logging: {
96
106
  enable: true,
97
- verboseEvents: true
98
- }
107
+ verboseEvents: true,
108
+ },
99
109
  });
100
110
 
101
111
  Object.assign(webex, {
102
- logger
112
+ logger,
103
113
  });
104
114
 
105
115
  Object.assign(webex.meetings, {
106
- startReachability: sinon.stub().returns(Promise.resolve())
116
+ startReachability: sinon.stub().returns(Promise.resolve()),
107
117
  });
108
118
 
109
119
  Object.assign(webex.internal, {
120
+ llm: {on: sinon.stub()},
110
121
  device: {
111
122
  deviceType: 'FAKE_DEVICE',
112
123
  register: sinon.stub().returns(Promise.resolve()),
113
- unregister: sinon.stub().returns(Promise.resolve())
124
+ unregister: sinon.stub().returns(Promise.resolve()),
114
125
  },
115
126
  mercury: {
116
127
  connect: sinon.stub().returns(Promise.resolve()),
117
128
  disconnect: sinon.stub().returns(Promise.resolve()),
118
129
  on: () => {},
119
- off: () => {}
130
+ off: () => {},
120
131
  },
121
132
  services: {
122
- getMeetingPreferences: sinon.stub().returns(Promise.resolve({
123
- sites: [
124
- {
125
- siteUrl: 'site1-example.webex.com',
126
- default: false
127
- },
128
- {
129
- siteUrl: 'site2-example.webex.com',
130
- default: false
131
- },
132
- {
133
- siteUrl: 'site3-example.webex.com',
134
- default: false
135
- },
136
- {
137
- siteUrl: 'go.webex.com',
138
- default: true
139
- }
140
- ]
141
- })),
142
- fetchClientRegionInfo: sinon.stub().returns(Promise.resolve())
133
+ getMeetingPreferences: sinon.stub().returns(
134
+ Promise.resolve({
135
+ sites: [
136
+ {
137
+ siteUrl: 'site1-example.webex.com',
138
+ default: false,
139
+ },
140
+ {
141
+ siteUrl: 'site2-example.webex.com',
142
+ default: false,
143
+ },
144
+ {
145
+ siteUrl: 'site3-example.webex.com',
146
+ default: false,
147
+ },
148
+ {
149
+ siteUrl: 'go.webex.com',
150
+ default: true,
151
+ },
152
+ ],
153
+ })
154
+ ),
155
+ fetchClientRegionInfo: sinon.stub().returns(Promise.resolve()),
143
156
  },
144
157
  metrics: {
145
- submitClientMetrics: sinon.stub().returns(Promise.resolve())
146
- }
147
-
158
+ submitClientMetrics: sinon.stub().returns(Promise.resolve()),
159
+ },
148
160
  });
149
161
  webex.emit('ready');
150
162
  });
151
163
 
164
+ afterEach(() => {
165
+ sinon.restore();
166
+ });
167
+
152
168
  it('has a webex instance with a meetings property', () => {
153
169
  assert.exists(webex, 'webex was initialized with children');
154
170
  assert.exists(webex.meetings, 'meetings child was set up on the webex instance');
@@ -178,10 +194,14 @@ describe('plugin-meetings', () => {
178
194
 
179
195
  describe('failure', () => {
180
196
  it('should not accept non boolean input', () => {
181
- const currentEnableUnifiedMeetings = webex.meetings.config.experimental.enableUnifiedMeetings;
197
+ const currentEnableUnifiedMeetings =
198
+ webex.meetings.config.experimental.enableUnifiedMeetings;
182
199
 
183
200
  webex.meetings._toggleUnifiedMeetings('test');
184
- assert.equal(webex.meetings.config.experimental.enableUnifiedMeetings, currentEnableUnifiedMeetings);
201
+ assert.equal(
202
+ webex.meetings.config.experimental.enableUnifiedMeetings,
203
+ currentEnableUnifiedMeetings
204
+ );
185
205
  });
186
206
  });
187
207
  });
@@ -203,7 +223,10 @@ describe('plugin-meetings', () => {
203
223
  const currentEnableAdhocMeetings = webex.meetings.config.experimental.enableAdhocMeetings;
204
224
 
205
225
  webex.meetings._toggleAdhocMeetings('test');
206
- assert.equal(webex.meetings.config.experimental.enableAdhocMeetings, currentEnableAdhocMeetings);
226
+ assert.equal(
227
+ webex.meetings.config.experimental.enableAdhocMeetings,
228
+ currentEnableAdhocMeetings
229
+ );
207
230
  });
208
231
  });
209
232
  });
@@ -228,18 +251,25 @@ describe('plugin-meetings', () => {
228
251
  const currentEnableTurnDiscovery = webex.meetings.config.experimental.enableTurnDiscovery;
229
252
 
230
253
  webex.meetings._toggleTurnDiscovery('test');
231
- assert.equal(webex.meetings.config.experimental.enableAdhocMeetings, currentEnableTurnDiscovery);
254
+ assert.equal(
255
+ webex.meetings.config.experimental.enableAdhocMeetings,
256
+ currentEnableTurnDiscovery
257
+ );
232
258
  });
233
259
  });
234
260
  });
235
261
 
236
-
237
262
  describe('Public API Contracts', () => {
238
263
  describe('#register', () => {
239
264
  it('emits an event and resolves when register succeeds', async () => {
240
265
  webex.canAuthorize = true;
241
266
  await webex.meetings.register();
242
- assert.calledWith(TriggerProxy.trigger, sinon.match.instanceOf(Meetings), {file: 'meetings', function: 'register'}, 'meetings:registered');
267
+ assert.calledWith(
268
+ TriggerProxy.trigger,
269
+ sinon.match.instanceOf(Meetings),
270
+ {file: 'meetings', function: 'register'},
271
+ 'meetings:registered'
272
+ );
243
273
  assert.isTrue(webex.meetings.registered);
244
274
  });
245
275
 
@@ -285,9 +315,15 @@ describe('plugin-meetings', () => {
285
315
  it('emits an event and resolves when unregister succeeds', (done) => {
286
316
  webex.meetings.registered = true;
287
317
  webex.meetings.unregister().then(() => {
288
- assert.calledWith(TriggerProxy.trigger, sinon.match.instanceOf(Meetings), {
289
- file: 'meetings', function: 'unregister'
290
- }, 'meetings:unregistered');
318
+ assert.calledWith(
319
+ TriggerProxy.trigger,
320
+ sinon.match.instanceOf(Meetings),
321
+ {
322
+ file: 'meetings',
323
+ function: 'unregister',
324
+ },
325
+ 'meetings:unregistered'
326
+ );
291
327
  assert.isFalse(webex.meetings.registered);
292
328
  done();
293
329
  });
@@ -325,7 +361,10 @@ describe('plugin-meetings', () => {
325
361
  it('does not get a reachability instance', () => {
326
362
  const reachability = webex.meetings.getReachability();
327
363
 
328
- assert.notExists(reachability, 'reachability is undefined because #setReachability has not been called');
364
+ assert.notExists(
365
+ reachability,
366
+ 'reachability is undefined because #setReachability has not been called'
367
+ );
329
368
  });
330
369
  });
331
370
  describe('after #setReachability', () => {
@@ -338,7 +377,10 @@ describe('plugin-meetings', () => {
338
377
  it('gets the reachability data instance from webex.meetings', () => {
339
378
  const reachability = webex.meetings.getReachability();
340
379
 
341
- assert.exists(reachability, 'reachability is defined because #setReachability has been called');
380
+ assert.exists(
381
+ reachability,
382
+ 'reachability is defined because #setReachability has been called'
383
+ );
342
384
  assert.instanceOf(reachability, Reachability, 'should be a reachability instance');
343
385
  });
344
386
  });
@@ -350,8 +392,15 @@ describe('plugin-meetings', () => {
350
392
  it('gets the personal meeting room instance from webex.meetings', () => {
351
393
  const personalMeetingRoom = webex.meetings.getPersonalMeetingRoom();
352
394
 
353
- assert.exists(personalMeetingRoom, 'personal meeting room instance is set up at object creation');
354
- assert.instanceOf(personalMeetingRoom, PersonalMeetingRoom, 'should be a personal meeting room instance');
395
+ assert.exists(
396
+ personalMeetingRoom,
397
+ 'personal meeting room instance is set up at object creation'
398
+ );
399
+ assert.instanceOf(
400
+ personalMeetingRoom,
401
+ PersonalMeetingRoom,
402
+ 'should be a personal meeting room instance'
403
+ );
355
404
  });
356
405
  });
357
406
  describe('Static shortcut proxy methods', () => {
@@ -380,11 +429,11 @@ describe('plugin-meetings', () => {
380
429
  describe('#getAllMeetings', () => {
381
430
  it('calls MeetingCollection to get all meetings with supplied options', () => {
382
431
  webex.meetings.getAllMeetings({
383
- test: test1
432
+ test: test1,
384
433
  });
385
434
  assert.calledOnce(webex.meetings.meetingCollection.getAll);
386
435
  assert.calledWith(webex.meetings.meetingCollection.getAll, {
387
- test: test1
436
+ test: test1,
388
437
  });
389
438
  });
390
439
  });
@@ -397,28 +446,28 @@ describe('plugin-meetings', () => {
397
446
  });
398
447
  describe('succesful requests', () => {
399
448
  beforeEach(() => {
400
- webex.meetings.request.getActiveMeetings = sinon.stub().returns(Promise.resolve({
401
- loci: [{
402
- url: url1
403
- }]
404
- }));
449
+ webex.meetings.request.getActiveMeetings = sinon.stub().returns(
450
+ Promise.resolve({
451
+ loci: [
452
+ {
453
+ url: url1,
454
+ },
455
+ ],
456
+ })
457
+ );
405
458
  });
406
459
  describe('when meeting is returned', () => {
407
- let parse;
408
460
 
409
461
  beforeEach(() => {
410
- parse = sinon.stub().returns(true);
411
462
  webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
412
- locusInfo: {
413
- parse
414
- }
463
+ locusInfo,
415
464
  });
416
465
  });
417
466
  it('tests the sync meeting calls for existing meeting', async () => {
418
467
  await webex.meetings.syncMeetings();
419
468
  assert.calledOnce(webex.meetings.request.getActiveMeetings);
420
469
  assert.calledOnce(webex.meetings.meetingCollection.getByKey);
421
- assert.calledOnce(parse);
470
+ assert.calledOnce(locusInfo.parse);
422
471
  assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
423
472
  });
424
473
  });
@@ -428,25 +477,32 @@ describe('plugin-meetings', () => {
428
477
  beforeEach(() => {
429
478
  initialSetup = sinon.stub().returns(true);
430
479
  webex.meetings.meetingCollection.getByKey = sinon.stub().returns(null);
431
- webex.meetings.create = sinon.stub().returns(Promise.resolve({
432
- locusInfo: {
433
- initialSetup
434
- }
435
- }));
480
+ webex.meetings.create = sinon.stub().returns(
481
+ Promise.resolve({
482
+ locusInfo: {
483
+ ...locusInfo,
484
+ initialSetup,
485
+ },
486
+ })
487
+ );
436
488
  });
437
489
  it('tests the sync meeting calls for not existing meeting', async () => {
438
490
  await webex.meetings.syncMeetings();
439
491
  assert.calledOnce(webex.meetings.request.getActiveMeetings);
440
- assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
492
+ assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
441
493
  assert.calledOnce(initialSetup);
442
494
  assert.calledOnce(webex.meetings.create);
443
495
  assert.calledWith(webex.meetings.request.getActiveMeetings);
444
496
  assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
445
- assert.calledWith(webex.meetings.create, {
446
- url: url1
447
- }, 'LOCUS_ID');
497
+ assert.calledWith(
498
+ webex.meetings.create,
499
+ {
500
+ url: url1,
501
+ },
502
+ 'LOCUS_ID'
503
+ );
448
504
  assert.calledWith(initialSetup, {
449
- url: url1
505
+ url: url1,
450
506
  });
451
507
  });
452
508
  });
@@ -457,28 +513,30 @@ describe('plugin-meetings', () => {
457
513
 
458
514
  beforeEach(() => {
459
515
  destroySpy = sinon.spy(webex.meetings, 'destroy');
460
- parse = sinon.stub().returns(true);
461
516
  initialSetup = sinon.stub().returns(true);
462
517
  webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
463
- locusInfo: {
464
- parse
465
- },
466
- sendCallAnalyzerMetrics: sinon.stub()
518
+ locusInfo,
519
+ sendCallAnalyzerMetrics: sinon.stub(),
467
520
  });
468
521
  webex.meetings.meetingCollection.getAll = sinon.stub().returns({
469
522
  meetingutk: {
470
- locusUrl: 'fdfdjfdhj', sendCallAnalyzerMetrics: sinon.stub()
471
- }
472
- });
473
- webex.meetings.create = sinon.stub().returns(Promise.resolve({
474
- locusInfo: {
475
- initialSetup
523
+ locusUrl: 'fdfdjfdhj',
524
+ sendCallAnalyzerMetrics: sinon.stub(),
476
525
  },
477
- sendCallAnalyzerMetrics: sinon.stub()
478
- }));
479
- webex.meetings.request.getActiveMeetings = sinon.stub().returns(Promise.resolve({
480
- loci: []
481
- }));
526
+ });
527
+ webex.meetings.create = sinon.stub().returns(
528
+ Promise.resolve({
529
+ locusInfo: {
530
+ initialSetup,
531
+ },
532
+ sendCallAnalyzerMetrics: sinon.stub(),
533
+ })
534
+ );
535
+ webex.meetings.request.getActiveMeetings = sinon.stub().returns(
536
+ Promise.resolve({
537
+ loci: [],
538
+ })
539
+ );
482
540
  MeetingUtil.cleanUp = sinon.stub().returns(Promise.resolve());
483
541
  });
484
542
  it('destroy non active meetings', async () => {
@@ -500,34 +558,29 @@ describe('plugin-meetings', () => {
500
558
  beforeEach(() => {
501
559
  infoOptions = {
502
560
  destination: 'dest-example',
503
- type: 'CONVERSATION_URL'
561
+ type: 'CONVERSATION_URL',
504
562
  };
505
563
  webex.meetings.meetingCollection.getByKey = sinon.stub().returns();
506
- webex.meetings.createMeeting = sinon.stub().returns(Promise.resolve({
507
- on: () => true
508
- }));
564
+ webex.meetings.createMeeting = sinon.stub().returns(
565
+ Promise.resolve({
566
+ on: () => true,
567
+ })
568
+ );
509
569
  });
510
570
 
511
- it('should call MeetingInfo#fetchInfoOptions() with proper params',
512
- () => {
513
- webex.meetings.meetingInfo.fetchInfoOptions = sinon.stub().resolves(
514
- infoOptions
515
- );
571
+ it('should call MeetingInfo#fetchInfoOptions() with proper params', () => {
572
+ webex.meetings.meetingInfo.fetchInfoOptions = sinon.stub().resolves(infoOptions);
516
573
 
517
- return webex.meetings.create(
574
+ return webex.meetings.create(infoOptions.destination, infoOptions.type).then(() => {
575
+ assert.calledWith(
576
+ webex.meetings.meetingInfo.fetchInfoOptions,
518
577
  infoOptions.destination,
519
578
  infoOptions.type
520
- )
521
- .then(() => {
522
- assert.calledWith(
523
- webex.meetings.meetingInfo.fetchInfoOptions,
524
- infoOptions.destination,
525
- infoOptions.type
526
- );
579
+ );
527
580
 
528
- assert.calledTwice(webex.meetings.meetingCollection.getByKey);
529
- });
581
+ assert.calledTwice(webex.meetings.meetingCollection.getByKey);
530
582
  });
583
+ });
531
584
 
532
585
  it('calls createMeeting and returns its promise', async () => {
533
586
  const FAKE_USE_RANDOM_DELAY = true;
@@ -536,7 +589,18 @@ describe('plugin-meetings', () => {
536
589
  assert.exists(create.then);
537
590
  await create;
538
591
  assert.calledOnce(webex.meetings.createMeeting);
539
- assert.calledWith(webex.meetings.createMeeting, test1, test2, FAKE_USE_RANDOM_DELAY);
592
+ assert.calledWith(webex.meetings.createMeeting, test1, test2, FAKE_USE_RANDOM_DELAY, {});
593
+ });
594
+
595
+ it('calls createMeeting with extra info params and returns its promise', async () => {
596
+ const FAKE_USE_RANDOM_DELAY = false;
597
+ const FAKE_INFO_EXTRA_PARAMS = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'};
598
+ const create = webex.meetings.create(test1, test2, FAKE_USE_RANDOM_DELAY, FAKE_INFO_EXTRA_PARAMS);
599
+
600
+ assert.exists(create.then);
601
+ await create;
602
+ assert.calledOnce(webex.meetings.createMeeting);
603
+ assert.calledWith(webex.meetings.createMeeting, test1, test2, FAKE_USE_RANDOM_DELAY, FAKE_INFO_EXTRA_PARAMS);
540
604
  });
541
605
 
542
606
  it('creates a new meeting when a scheduled meeting exists in the conversation', async () => {
@@ -566,9 +630,9 @@ describe('plugin-meetings', () => {
566
630
  return undefined;
567
631
  });
568
632
 
569
- webex.meetings.meetingInfo.fetchInfoOptions = sinon.stub().resolves(
570
- scheduledMeetingFixture
571
- );
633
+ webex.meetings.meetingInfo.fetchInfoOptions = sinon
634
+ .stub()
635
+ .resolves(scheduledMeetingFixture);
572
636
 
573
637
  webex.meetings.meetingCollection.set(scheduledMeetingFixture);
574
638
 
@@ -603,99 +667,125 @@ describe('plugin-meetings', () => {
603
667
  it('doesnt call handle locus mercury for a locus roap event', () => {
604
668
  webex.meetings.handleLocusMercury({
605
669
  data: {
606
- eventType: 'locus.message.roap'
607
- }
670
+ eventType: 'locus.message.roap',
671
+ },
608
672
  });
609
673
  assert.notCalled(webex.meetings.handleLocusEvent);
610
674
  });
611
675
  it('doesnt call handle locus mercury for an undefined eventType', () => {
612
676
  webex.meetings.handleLocusMercury({
613
- data: {
614
- }
677
+ data: {},
615
678
  });
616
679
  assert.notCalled(webex.meetings.handleLocusEvent);
617
680
  });
618
681
  it('calls handle locus mercury for all locus events', () => {
619
682
  webex.meetings.handleLocusMercury({
620
683
  data: {
621
- eventType: test1
622
- }
684
+ eventType: test1,
685
+ },
623
686
  });
624
687
  assert.calledOnce(webex.meetings.handleLocusEvent);
625
- assert.calledWith(webex.meetings.handleLocusEvent, {
626
- eventType: test1
627
- }, true);
688
+ assert.calledWith(
689
+ webex.meetings.handleLocusEvent,
690
+ {
691
+ eventType: test1,
692
+ },
693
+ true
694
+ );
628
695
  });
629
696
  });
630
697
  describe('#handleLocusEvent', () => {
631
698
  describe('there was a meeting', () => {
632
- let parse;
633
699
 
634
700
  beforeEach(() => {
635
- parse = sinon.stub().returns(true);
636
701
  webex.meetings.meetingCollection.getByKey = sinon.stub().returns({
637
- locusInfo: {
638
- parse
639
- }
702
+ locusInfo,
640
703
  });
641
704
  });
642
- it('should parse the meeting info', () => {
705
+ it('should parse the meeting info and update main session locus cache', () => {
706
+ sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(false);
643
707
  webex.meetings.handleLocusEvent({
644
- locusUrl: url1
708
+ locusUrl: url1,
645
709
  });
646
710
  assert.calledOnce(webex.meetings.meetingCollection.getByKey);
647
711
  assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
648
- assert.calledOnce(parse);
649
- assert.calledWith(parse, {
650
- locusInfo: {
651
- parse
712
+ assert.calledOnce(locusInfo.parse);
713
+ assert.calledOnce(locusInfo.updateMainSessionLocusCache);
714
+ assert.calledWith(
715
+ locusInfo.parse,
716
+ {
717
+ locusInfo,
718
+ },
719
+ {
720
+ locusUrl: url1,
652
721
  }
653
- }, {
654
- locusUrl: url1
722
+ );
723
+ });
724
+
725
+ it('should not update main session locus cache', () => {
726
+ sinon.stub(MeetingsUtil, 'isBreakoutLocusDTO').returns(true);
727
+ webex.meetings.handleLocusEvent({
728
+ locusUrl: url1,
655
729
  });
730
+ assert.notCalled(locusInfo.updateMainSessionLocusCache);
656
731
  });
657
732
  });
658
733
  describe('there was not a meeting', () => {
659
734
  let initialSetup;
735
+ const webExMeetingId = '123456';
660
736
 
661
737
  beforeEach(() => {
662
738
  initialSetup = sinon.stub().returns(true);
663
739
  webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
664
- webex.meetings.create = sinon.stub().returns(Promise.resolve({
665
- locusInfo: {
666
- initialSetup
667
- }
668
- }));
740
+ webex.meetings.create = sinon.stub().returns(
741
+ Promise.resolve({
742
+ locusInfo: {
743
+ ...locusInfo,
744
+ initialSetup,
745
+ },
746
+ })
747
+ );
669
748
  });
670
749
  it('should setup the meeting by difference event', async () => {
671
750
  await webex.meetings.handleLocusEvent({
672
751
  locus: {
673
752
  id: uuid1,
674
- replaces: [{
675
- locusUrl: 'http:locusUrl'
676
- }],
753
+ replaces: [
754
+ {
755
+ locusUrl: 'http:locusUrl',
756
+ },
757
+ ],
677
758
  self: {
678
759
  callBackInfo: {
679
- callbackAddress: uri1
680
- }
681
- }
760
+ callbackAddress: uri1,
761
+ },
762
+ },
763
+ info: {
764
+ webExMeetingId
765
+ },
682
766
  },
683
767
  eventType: 'locus.difference',
684
- locusUrl: url1
768
+ locusUrl: url1,
685
769
  });
686
- assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
770
+ assert.callCount(webex.meetings.meetingCollection.getByKey, 6);
687
771
  assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
772
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', webExMeetingId);
688
773
  assert.calledOnce(initialSetup);
689
774
  assert.calledWith(initialSetup, {
690
775
  id: uuid1,
691
- replaces: [{
692
- locusUrl: 'http:locusUrl'
693
- }],
776
+ replaces: [
777
+ {
778
+ locusUrl: 'http:locusUrl',
779
+ },
780
+ ],
694
781
  self: {
695
782
  callBackInfo: {
696
- callbackAddress: uri1
697
- }
698
- }
783
+ callbackAddress: uri1,
784
+ },
785
+ },
786
+ info: {
787
+ webExMeetingId
788
+ },
699
789
  });
700
790
  });
701
791
  it('should setup the meeting by difference event without replaces', async () => {
@@ -704,23 +794,30 @@ describe('plugin-meetings', () => {
704
794
  id: uuid1,
705
795
  self: {
706
796
  callBackInfo: {
707
- callbackAddress: uri1
708
- }
709
- }
797
+ callbackAddress: uri1,
798
+ },
799
+ },
800
+ info: {
801
+ webExMeetingId
802
+ },
710
803
  },
711
804
  eventType: 'locus.difference',
712
- locusUrl: url1
805
+ locusUrl: url1,
713
806
  });
714
- assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
807
+ assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
715
808
  assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
809
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', webExMeetingId);
716
810
  assert.calledOnce(initialSetup);
717
811
  assert.calledWith(initialSetup, {
718
812
  id: uuid1,
719
813
  self: {
720
814
  callBackInfo: {
721
- callbackAddress: uri1
722
- }
723
- }
815
+ callbackAddress: uri1,
816
+ },
817
+ },
818
+ info: {
819
+ webExMeetingId
820
+ },
724
821
  });
725
822
  });
726
823
  it('should setup the meeting by a not difference event', async () => {
@@ -729,23 +826,30 @@ describe('plugin-meetings', () => {
729
826
  id: uuid1,
730
827
  self: {
731
828
  callBackInfo: {
732
- callbackAddress: uri1
733
- }
734
- }
829
+ callbackAddress: uri1,
830
+ },
831
+ },
832
+ info: {
833
+ webExMeetingId
834
+ },
735
835
  },
736
836
  eventType: test1,
737
- locusUrl: url1
837
+ locusUrl: url1,
738
838
  });
739
- assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
839
+ assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
740
840
  assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
841
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', webExMeetingId);
741
842
  assert.calledOnce(initialSetup);
742
843
  assert.calledWith(initialSetup, {
743
844
  id: uuid1,
744
845
  self: {
745
846
  callBackInfo: {
746
- callbackAddress: uri1
747
- }
748
- }
847
+ callbackAddress: uri1,
848
+ },
849
+ },
850
+ info: {
851
+ webExMeetingId
852
+ },
749
853
  });
750
854
  });
751
855
 
@@ -754,13 +858,13 @@ describe('plugin-meetings', () => {
754
858
  id: uuid1,
755
859
  self: {
756
860
  callbackInfo: {
757
- callbackAddress: uri1
758
- }
861
+ callbackAddress: uri1,
862
+ },
759
863
  },
760
864
  info: {
761
- isUnifiedSpaceMeeting
865
+ isUnifiedSpaceMeeting,
762
866
  },
763
- conversationUrl: 'fakeConvoUrl'
867
+ conversationUrl: 'fakeConvoUrl',
764
868
  },
765
869
  eventType: test1,
766
870
  locusUrl: url1,
@@ -768,26 +872,46 @@ describe('plugin-meetings', () => {
768
872
 
769
873
  it('should not try to match USM meetings by conversation url', async () => {
770
874
  await webex.meetings.handleLocusEvent(generateFakeLocusData(true));
771
- assert.callCount(webex.meetings.meetingCollection.getByKey, 3);
772
- assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, ['locusUrl', url1]);
773
- assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(1).args, ['correlationId', false]);
774
- assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(2).args, ['sipUri', uri1]);
875
+ assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
876
+ assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
877
+ 'locusUrl',
878
+ url1,
879
+ ]);
880
+ assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(1).args, [
881
+ 'correlationId',
882
+ false,
883
+ ]);
884
+ assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(2).args, [
885
+ 'sipUri',
886
+ uri1,
887
+ ]);
775
888
  assert.calledOnce(initialSetup);
776
889
  });
777
890
  it('should try to match non-USM meetings by conversation url', async () => {
778
891
  await webex.meetings.handleLocusEvent(generateFakeLocusData(false));
779
- assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
780
- assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, ['locusUrl', url1]);
781
- assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(1).args, ['correlationId', false]);
782
- assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(2).args, ['sipUri', uri1]);
783
- assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(3).args, ['conversationUrl', 'fakeConvoUrl']);
892
+ assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
893
+ assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(0).args, [
894
+ 'locusUrl',
895
+ url1,
896
+ ]);
897
+ assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(1).args, [
898
+ 'correlationId',
899
+ false,
900
+ ]);
901
+ assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(2).args, [
902
+ 'sipUri',
903
+ uri1,
904
+ ]);
905
+ assert.deepEqual(webex.meetings.meetingCollection.getByKey.getCall(3).args, [
906
+ 'conversationUrl',
907
+ 'fakeConvoUrl',
908
+ ]);
784
909
  assert.calledOnce(initialSetup);
785
910
  });
786
911
  });
787
912
  });
788
913
  describe('#createMeeting', () => {
789
914
  beforeEach(() => {
790
- MediaUtil.createPeerConnection = sinon.stub().returns(true);
791
915
  webex.internal.device.userId = uuid1;
792
916
  webex.internal.device.url = url1;
793
917
  MeetingCollection.set = sinon.stub().returns(true);
@@ -796,15 +920,19 @@ describe('plugin-meetings', () => {
796
920
  });
797
921
  describe('successful MeetingInfo.#fetchMeetingInfo', () => {
798
922
  let clock, setTimeoutSpy, fakeMeetingStartTimeString, FAKE_TIME_TO_START;
923
+ const FAKE_INFO_EXTRA_PARAMS = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'};
799
924
 
800
925
  beforeEach(() => {
801
926
  clock = sinon.useFakeTimers();
802
927
  setTimeoutSpy = sinon.spy(clock, 'setTimeout');
803
- webex.meetings.meetingInfo.fetchMeetingInfo = sinon.stub().returns(Promise.resolve({
804
- body: {
805
- permissionToken: 'PT', meetingJoinUrl: 'meetingJoinUrl'
806
- }
807
- }));
928
+ webex.meetings.meetingInfo.fetchMeetingInfo = sinon.stub().returns(
929
+ Promise.resolve({
930
+ body: {
931
+ permissionToken: 'PT',
932
+ meetingJoinUrl: 'meetingJoinUrl',
933
+ },
934
+ })
935
+ );
808
936
  const nowTimeStamp = Date.now();
809
937
 
810
938
  FAKE_TIME_TO_START = 0.1 * 60 * 1000;
@@ -818,12 +946,18 @@ describe('plugin-meetings', () => {
818
946
  clock.restore();
819
947
  });
820
948
 
821
- const checkCreateWithoutDelay = (meeting, destination, type, expectedMeetingData = {}) => {
949
+ const checkCreateWithoutDelay = (
950
+ meeting,
951
+ destination,
952
+ type,
953
+ extraParams = {},
954
+ expectedMeetingData = {}
955
+ ) => {
822
956
  assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
823
957
  assert.calledOnce(MeetingsUtil.getMeetingAddedType);
824
958
  assert.notCalled(setTimeoutSpy);
825
959
  assert.calledThrice(TriggerProxy.trigger);
826
- assert.calledWith(webex.meetings.meetingInfo.fetchMeetingInfo, destination, type);
960
+ assert.calledWith(webex.meetings.meetingInfo.fetchMeetingInfo, destination, type, null, null, undefined, undefined, extraParams);
827
961
  assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
828
962
 
829
963
  if (expectedMeetingData.permissionToken) {
@@ -834,93 +968,145 @@ describe('plugin-meetings', () => {
834
968
  }
835
969
  assert.equal(meeting.destination, destination);
836
970
  assert.equal(meeting.destinationType, type);
837
- assert.calledWith(TriggerProxy.trigger, sinon.match.instanceOf(Meetings), {
838
- file: 'meetings', function: 'createMeeting'
839
- }, 'meeting:added', {
840
- meeting: sinon.match.instanceOf(Meeting), type: 'test meeting added type'
841
- });
842
- assert.calledWith(TriggerProxy.trigger, meeting, {file: 'meetings', function: 'fetchMeetingInfo'}, 'meeting:meetingInfoAvailable');
971
+ assert.calledWith(
972
+ TriggerProxy.trigger,
973
+ sinon.match.instanceOf(Meetings),
974
+ {
975
+ file: 'meetings',
976
+ function: 'createMeeting',
977
+ },
978
+ 'meeting:added',
979
+ {
980
+ meeting: sinon.match.instanceOf(Meeting),
981
+ type: 'test meeting added type',
982
+ }
983
+ );
984
+ assert.calledWith(
985
+ TriggerProxy.trigger,
986
+ meeting,
987
+ {file: 'meetings', function: 'fetchMeetingInfo'},
988
+ 'meeting:meetingInfoAvailable'
989
+ );
843
990
  };
844
-
991
+
845
992
  it('creates the meeting from a successful meeting info fetch promise testing', async () => {
846
993
  const meeting = await webex.meetings.createMeeting('test destination', 'test type');
847
994
 
848
995
  const expectedMeetingData = {
849
996
  permissionToken: 'PT',
850
- meetingJoinUrl: 'meetingJoinUrl'
851
- };
852
-
853
- checkCreateWithoutDelay(meeting, 'test destination', 'test type', expectedMeetingData);
854
- });
855
-
856
- it('creates the meeting from a successful meeting info fetch meeting resolve testing', async () => {
857
- const meeting = await webex.meetings.createMeeting('test destination', 'test type');
858
- const expectedMeetingData = {
859
- permissionToken: 'PT',
860
- meetingJoinUrl: 'meetingJoinUrl'
997
+ meetingJoinUrl: 'meetingJoinUrl',
861
998
  };
862
999
 
863
- assert.instanceOf(meeting, Meeting, 'createMeeting should eventually resolve to a Meeting Object');
864
- checkCreateWithoutDelay(meeting, 'test destination', 'test type', expectedMeetingData);
1000
+ checkCreateWithoutDelay(meeting, 'test destination', 'test type', {}, expectedMeetingData);
865
1001
  });
866
1002
 
867
- it('creates the meeting from a successful meeting info fetch with random delay', async () => {
868
- const FAKE_LOCUS_MEETING = {
869
- conversationUrl: 'locusConvURL',
870
- url: 'locusUrl',
871
- info: {
872
- webExMeetingId: 'locusMeetingId',
873
- sipUri: 'locusSipUri',
874
- owner: 'locusOwner'
875
- },
876
- meeting: {
877
- startTime: fakeMeetingStartTimeString
878
- },
879
- fullState: {
880
- active: false
881
- }
882
- };
883
-
884
- const meeting = await webex.meetings.createMeeting(FAKE_LOCUS_MEETING, 'test type', true);
885
-
886
- assert.instanceOf(meeting, Meeting, 'createMeeting should eventually resolve to a Meeting Object');
887
- assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
888
- assert.calledOnce(setTimeoutSpy);
889
-
890
- // Parse meeting info with locus object
891
- assert.equal(meeting.conversationUrl, 'locusConvURL');
892
- assert.equal(meeting.locusUrl, 'locusUrl');
893
- assert.equal(meeting.sipUri, 'locusSipUri');
894
- assert.equal(meeting.meetingNumber, 'locusMeetingId');
895
- assert.isUndefined(meeting.meetingJoinUrl);
896
- assert.equal(meeting.owner, 'locusOwner');
897
- assert.isUndefined(meeting.permissionToken);
898
-
899
- // Add meeting and send trigger
900
- assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
901
- assert.calledTwice(TriggerProxy.trigger);
902
- assert.calledWith(TriggerProxy.trigger, sinon.match.instanceOf(Meetings), {
903
- file: 'meetings', function: 'createMeeting'
904
- }, 'meeting:added', {
905
- meeting: sinon.match.instanceOf(Meeting), type: 'test meeting added type'
1003
+ [undefined, FAKE_INFO_EXTRA_PARAMS].forEach((infoExtraParams) => {
1004
+ const infoExtraParamsProvided = infoExtraParams !== undefined;
1005
+
1006
+ it(`creates the meeting from a successful meeting info fetch meeting resolve testing${infoExtraParamsProvided ? ' with infoExtraParams' : ''}`, async () => {
1007
+ const meeting = await webex.meetings.createMeeting('test destination', 'test type', false, infoExtraParams);
1008
+ const expectedMeetingData = {
1009
+ permissionToken: 'PT',
1010
+ meetingJoinUrl: 'meetingJoinUrl',
1011
+ };
1012
+
1013
+ assert.instanceOf(
1014
+ meeting,
1015
+ Meeting,
1016
+ 'createMeeting should eventually resolve to a Meeting Object'
1017
+ );
1018
+ checkCreateWithoutDelay(meeting, 'test destination', 'test type', infoExtraParamsProvided ? infoExtraParams : {}, expectedMeetingData);
906
1019
  });
907
-
908
- // When timer expires
909
- clock.tick(FAKE_TIME_TO_START);
910
- assert.calledWith(webex.meetings.meetingInfo.fetchMeetingInfo, FAKE_LOCUS_MEETING, 'test type');
911
-
912
- // Parse meeting info is called again with new meeting info
913
- await testUtils.flushPromises();
914
- assert.equal(meeting.conversationUrl, 'locusConvURL');
915
- assert.equal(meeting.locusUrl, 'locusUrl');
916
- assert.equal(meeting.sipUri, 'locusSipUri');
917
- assert.equal(meeting.meetingNumber, 'locusMeetingId');
918
- assert.equal(meeting.meetingJoinUrl, 'meetingJoinUrl');
919
- assert.equal(meeting.owner, 'locusOwner');
920
- assert.equal(meeting.permissionToken, 'PT');
921
-
922
- assert.calledWith(TriggerProxy.trigger, meeting, {file: 'meetings', function: 'fetchMeetingInfo'}, 'meeting:meetingInfoAvailable');
923
- });
1020
+
1021
+ it(`creates the meeting from a successful meeting info fetch with random delay${infoExtraParamsProvided ? ' with infoExtraParams' : ''}`, async () => {
1022
+ const FAKE_LOCUS_MEETING = {
1023
+ conversationUrl: 'locusConvURL',
1024
+ url: 'locusUrl',
1025
+ info: {
1026
+ webExMeetingId: 'locusMeetingId',
1027
+ sipUri: 'locusSipUri',
1028
+ owner: 'locusOwner',
1029
+ },
1030
+ meeting: {
1031
+ startTime: fakeMeetingStartTimeString,
1032
+ },
1033
+ fullState: {
1034
+ active: false,
1035
+ },
1036
+ };
1037
+
1038
+ const meeting = await webex.meetings.createMeeting(
1039
+ FAKE_LOCUS_MEETING,
1040
+ 'test type',
1041
+ true,
1042
+ infoExtraParams
1043
+ );
1044
+
1045
+ assert.instanceOf(
1046
+ meeting,
1047
+ Meeting,
1048
+ 'createMeeting should eventually resolve to a Meeting Object'
1049
+ );
1050
+ assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
1051
+ assert.calledOnce(setTimeoutSpy);
1052
+
1053
+ // Parse meeting info with locus object
1054
+ assert.equal(meeting.conversationUrl, 'locusConvURL');
1055
+ assert.equal(meeting.locusUrl, 'locusUrl');
1056
+ assert.equal(meeting.sipUri, 'locusSipUri');
1057
+ assert.equal(meeting.meetingNumber, 'locusMeetingId');
1058
+ assert.isUndefined(meeting.meetingJoinUrl);
1059
+ assert.equal(meeting.owner, 'locusOwner');
1060
+ assert.isUndefined(meeting.permissionToken);
1061
+
1062
+ // Add meeting and send trigger
1063
+ assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
1064
+ assert.calledTwice(TriggerProxy.trigger);
1065
+ assert.calledWith(
1066
+ TriggerProxy.trigger,
1067
+ sinon.match.instanceOf(Meetings),
1068
+ {
1069
+ file: 'meetings',
1070
+ function: 'createMeeting',
1071
+ },
1072
+ 'meeting:added',
1073
+ {
1074
+ meeting: sinon.match.instanceOf(Meeting),
1075
+ type: 'test meeting added type',
1076
+ }
1077
+ );
1078
+
1079
+ // When timer expires
1080
+ clock.tick(FAKE_TIME_TO_START);
1081
+ assert.calledWith(
1082
+ webex.meetings.meetingInfo.fetchMeetingInfo,
1083
+ FAKE_LOCUS_MEETING,
1084
+ 'test type',
1085
+ null,
1086
+ null,
1087
+ undefined,
1088
+ undefined,
1089
+ infoExtraParamsProvided ? infoExtraParams : {}
1090
+ );
1091
+
1092
+ // Parse meeting info is called again with new meeting info
1093
+ await testUtils.flushPromises();
1094
+ assert.equal(meeting.conversationUrl, 'locusConvURL');
1095
+ assert.equal(meeting.locusUrl, 'locusUrl');
1096
+ assert.equal(meeting.sipUri, 'locusSipUri');
1097
+ assert.equal(meeting.meetingNumber, 'locusMeetingId');
1098
+ assert.equal(meeting.meetingJoinUrl, 'meetingJoinUrl');
1099
+ assert.equal(meeting.owner, 'locusOwner');
1100
+ assert.equal(meeting.permissionToken, 'PT');
1101
+
1102
+ assert.calledWith(
1103
+ TriggerProxy.trigger,
1104
+ meeting,
1105
+ {file: 'meetings', function: 'fetchMeetingInfo'},
1106
+ 'meeting:meetingInfoAvailable'
1107
+ );
1108
+ });
1109
+ })
924
1110
 
925
1111
  it('creates the meeting from a successful meeting info fetch that has no random delay because it is active', async () => {
926
1112
  const FAKE_LOCUS_MEETING = {
@@ -929,19 +1115,27 @@ describe('plugin-meetings', () => {
929
1115
  info: {
930
1116
  webExMeetingId: 'locusMeetingId',
931
1117
  sipUri: 'locusSipUri',
932
- owner: 'locusOwner'
1118
+ owner: 'locusOwner',
933
1119
  },
934
1120
  meeting: {
935
- startTime: fakeMeetingStartTimeString
1121
+ startTime: fakeMeetingStartTimeString,
936
1122
  },
937
1123
  fullState: {
938
- active: true
939
- }
1124
+ active: true,
1125
+ },
940
1126
  };
941
1127
 
942
- const meeting = await webex.meetings.createMeeting(FAKE_LOCUS_MEETING, 'test type', true);
1128
+ const meeting = await webex.meetings.createMeeting(
1129
+ FAKE_LOCUS_MEETING,
1130
+ 'test type',
1131
+ true
1132
+ );
943
1133
 
944
- assert.instanceOf(meeting, Meeting, 'createMeeting should eventually resolve to a Meeting Object');
1134
+ assert.instanceOf(
1135
+ meeting,
1136
+ Meeting,
1137
+ 'createMeeting should eventually resolve to a Meeting Object'
1138
+ );
945
1139
  checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
946
1140
  });
947
1141
 
@@ -952,27 +1146,35 @@ describe('plugin-meetings', () => {
952
1146
  info: {
953
1147
  webExMeetingId: 'locusMeetingId',
954
1148
  sipUri: 'locusSipUri',
955
- owner: 'locusOwner'
1149
+ owner: 'locusOwner',
956
1150
  },
957
1151
  meeting: {
958
- startTime: fakeMeetingStartTimeString - (1 * 60 * 60 * 1000)
1152
+ startTime: fakeMeetingStartTimeString - 1 * 60 * 60 * 1000,
959
1153
  },
960
1154
  fullState: {
961
- active: false
962
- }
1155
+ active: false,
1156
+ },
963
1157
  };
964
1158
 
965
- const meeting = await webex.meetings.createMeeting(FAKE_LOCUS_MEETING, 'test type', true);
1159
+ const meeting = await webex.meetings.createMeeting(
1160
+ FAKE_LOCUS_MEETING,
1161
+ 'test type',
1162
+ true
1163
+ );
966
1164
 
967
- assert.instanceOf(meeting, Meeting, 'createMeeting should eventually resolve to a Meeting Object');
1165
+ assert.instanceOf(
1166
+ meeting,
1167
+ Meeting,
1168
+ 'createMeeting should eventually resolve to a Meeting Object'
1169
+ );
968
1170
  checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
969
1171
  });
970
1172
 
971
1173
  it('creates the meeting from a successful meeting info fetch that has no random delay because enableUnifiedMeetings is disabled', async () => {
972
1174
  Object.assign(webex.meetings.config, {
973
1175
  experimental: {
974
- enableUnifiedMeetings: false
975
- }
1176
+ enableUnifiedMeetings: false,
1177
+ },
976
1178
  });
977
1179
  const FAKE_LOCUS_MEETING = {
978
1180
  conversationUrl: 'locusConvURL',
@@ -980,19 +1182,27 @@ describe('plugin-meetings', () => {
980
1182
  info: {
981
1183
  webExMeetingId: 'locusMeetingId',
982
1184
  sipUri: 'locusSipUri',
983
- owner: 'locusOwner'
1185
+ owner: 'locusOwner',
984
1186
  },
985
1187
  meeting: {
986
- startTime: fakeMeetingStartTimeString
1188
+ startTime: fakeMeetingStartTimeString,
987
1189
  },
988
1190
  fullState: {
989
- active: false
990
- }
1191
+ active: false,
1192
+ },
991
1193
  };
992
1194
 
993
- const meeting = await webex.meetings.createMeeting(FAKE_LOCUS_MEETING, 'test type', true);
1195
+ const meeting = await webex.meetings.createMeeting(
1196
+ FAKE_LOCUS_MEETING,
1197
+ 'test type',
1198
+ true
1199
+ );
994
1200
 
995
- assert.instanceOf(meeting, Meeting, 'createMeeting should eventually resolve to a Meeting Object');
1201
+ assert.instanceOf(
1202
+ meeting,
1203
+ Meeting,
1204
+ 'createMeeting should eventually resolve to a Meeting Object'
1205
+ );
996
1206
  checkCreateWithoutDelay(meeting, FAKE_LOCUS_MEETING, 'test type');
997
1207
  });
998
1208
  });
@@ -1001,30 +1211,104 @@ describe('plugin-meetings', () => {
1001
1211
  beforeEach(() => {
1002
1212
  console.error = sinon.stub().returns(false);
1003
1213
  TriggerProxy.trigger.reset();
1004
- webex.meetings.meetingInfo.fetchMeetingInfo = sinon.stub().returns(Promise.reject(new Error('test')));
1214
+ webex.meetings.meetingInfo.fetchMeetingInfo = sinon
1215
+ .stub()
1216
+ .returns(Promise.reject(new Error('test')));
1005
1217
  });
1006
1218
  it('creates the meeting from a rejected meeting info fetch', async () => {
1007
1219
  const meeting = await webex.meetings.createMeeting('test destination', 'test type');
1008
1220
 
1009
- assert.instanceOf(meeting, Meeting, 'createMeeting should eventually resolve to a Meeting Object');
1221
+ assert.instanceOf(
1222
+ meeting,
1223
+ Meeting,
1224
+ 'createMeeting should eventually resolve to a Meeting Object'
1225
+ );
1010
1226
  assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
1011
1227
  assert.calledOnce(MeetingsUtil.getMeetingAddedType);
1012
1228
  assert.calledTwice(TriggerProxy.trigger);
1013
- assert.calledWith(webex.meetings.meetingInfo.fetchMeetingInfo, 'test destination', 'test type');
1229
+ assert.calledWith(
1230
+ webex.meetings.meetingInfo.fetchMeetingInfo,
1231
+ 'test destination',
1232
+ 'test type'
1233
+ );
1014
1234
  assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
1015
- assert.calledWith(TriggerProxy.trigger, sinon.match.instanceOf(Meetings), {
1016
- file: 'meetings', function: 'createMeeting'
1017
- }, 'meeting:added', {
1018
- meeting: sinon.match.instanceOf(Meeting), type: 'test meeting added type'
1019
- });
1235
+ assert.calledWith(
1236
+ TriggerProxy.trigger,
1237
+ sinon.match.instanceOf(Meetings),
1238
+ {
1239
+ file: 'meetings',
1240
+ function: 'createMeeting',
1241
+ },
1242
+ 'meeting:added',
1243
+ {
1244
+ meeting: sinon.match.instanceOf(Meeting),
1245
+ type: 'test meeting added type',
1246
+ }
1247
+ );
1020
1248
  });
1021
1249
  });
1250
+
1251
+ describe('rejected MeetingInfo.#fetchMeetingInfo - does not log for known Error types', () => {
1252
+ forEach(
1253
+ [
1254
+ {
1255
+ error: new CaptchaError(),
1256
+ debugLogMessage:
1257
+ 'Meetings:index#createMeeting --> Debug CaptchaError: Captcha is required. fetching /meetingInfo for creation.',
1258
+ },
1259
+ {
1260
+ error: new PasswordError(),
1261
+ debugLogMessage:
1262
+ 'Meetings:index#createMeeting --> Debug PasswordError: Password is required, please use verifyPassword() fetching /meetingInfo for creation.',
1263
+ },
1264
+ {
1265
+ error: new PermissionError(),
1266
+ debugLogMessage:
1267
+ 'Meetings:index#createMeeting --> Debug PermissionError: Not allowed to execute the function, some properties on server, or local client state do not allow you to complete this action. fetching /meetingInfo for creation.',
1268
+ },
1269
+ {
1270
+ error: new Error(),
1271
+ infoLogMessage: true,
1272
+ debugLogMessage:
1273
+ 'Meetings:index#createMeeting --> Debug Error fetching /meetingInfo for creation.',
1274
+ },
1275
+ ],
1276
+ ({error, debugLogMessage, infoLogMessage}) => {
1277
+ it('creates the meeting from a rejected meeting info fetch', async () => {
1278
+ webex.meetings.meetingInfo.fetchMeetingInfo = sinon
1279
+ .stub()
1280
+ .returns(Promise.reject(error));
1281
+
1282
+ LoggerProxy.logger.debug = sinon.stub();
1283
+ LoggerProxy.logger.info = sinon.stub();
1284
+
1285
+ const meeting = await webex.meetings.createMeeting('test destination', 'test type');
1286
+
1287
+ assert.instanceOf(
1288
+ meeting,
1289
+ Meeting,
1290
+ 'createMeeting should eventually resolve to a Meeting Object'
1291
+ );
1292
+
1293
+ assert.calledWith(LoggerProxy.logger.debug, debugLogMessage);
1294
+
1295
+ if (infoLogMessage) {
1296
+ assert.calledWith(
1297
+ LoggerProxy.logger.info,
1298
+ 'Meetings:index#createMeeting --> Info Unable to fetch meeting info for test destination.'
1299
+ );
1300
+ } else {
1301
+ assert.notCalled(LoggerProxy.logger.info);
1302
+ }
1303
+ });
1304
+ }
1305
+ );
1306
+ });
1022
1307
  });
1023
1308
  });
1024
1309
  describe('Public Event Triggers', () => {
1025
1310
  describe('#destroy', () => {
1026
1311
  beforeEach(() => {
1027
- MediaUtil.createPeerConnection = sinon.stub().returns(true);
1028
1312
  MeetingUtil.cleanUp = sinon.stub();
1029
1313
  });
1030
1314
  it('should have #destroy', () => {
@@ -1042,11 +1326,19 @@ describe('plugin-meetings', () => {
1042
1326
 
1043
1327
  assert.calledOnce(webex.meetings.meetingCollection.delete);
1044
1328
  assert.calledWith(webex.meetings.meetingCollection.delete, meeting.id);
1045
- assert.calledWith(TriggerProxy.trigger, sinon.match.instanceOf(Meetings), {
1046
- file: 'meetings', function: 'destroy'
1047
- }, 'meeting:removed', {
1048
- meetingId: meeting.id, reason: test1
1049
- });
1329
+ assert.calledWith(
1330
+ TriggerProxy.trigger,
1331
+ sinon.match.instanceOf(Meetings),
1332
+ {
1333
+ file: 'meetings',
1334
+ function: 'destroy',
1335
+ },
1336
+ 'meeting:removed',
1337
+ {
1338
+ meetingId: meeting.id,
1339
+ reason: test1,
1340
+ }
1341
+ );
1050
1342
  });
1051
1343
  });
1052
1344
 
@@ -1071,7 +1363,8 @@ describe('plugin-meetings', () => {
1071
1363
  it('should trigger event upon mercury disconnect', () => {
1072
1364
  const {meetings} = webex;
1073
1365
  const SCOPE = {
1074
- file: 'meetings/index', function: 'handleMercuryOffline'
1366
+ file: 'meetings/index',
1367
+ function: 'handleMercuryOffline',
1075
1368
  };
1076
1369
  const EVENT = 'network:disconnected';
1077
1370
 
@@ -1101,13 +1394,11 @@ describe('plugin-meetings', () => {
1101
1394
  services: {
1102
1395
  getMeetingPreferences: sinon.stub().returns(Promise.resolve({})),
1103
1396
  },
1104
-
1105
1397
  });
1106
1398
 
1107
- await webex.meetings.fetchUserPreferredWebexSite()
1108
- .then(() => {
1109
- assert.equal(webex.meetings.preferredWebexSite, '');
1110
- });
1399
+ await webex.meetings.fetchUserPreferredWebexSite().then(() => {
1400
+ assert.equal(webex.meetings.preferredWebexSite, '');
1401
+ });
1111
1402
  });
1112
1403
  });
1113
1404
  });
@@ -1116,7 +1407,6 @@ describe('plugin-meetings', () => {
1116
1407
  let meeting;
1117
1408
 
1118
1409
  beforeEach(async () => {
1119
- MediaUtil.createPeerConnection = sinon.stub().returns(true);
1120
1410
  webex.internal.device.userId = uuid1;
1121
1411
  webex.internal.device.url = url1;
1122
1412
  MeetingCollection.set = sinon.stub().returns(true);
@@ -1124,11 +1414,14 @@ describe('plugin-meetings', () => {
1124
1414
  TriggerProxy.trigger.reset();
1125
1415
  // clock = sinon.useFakeTimers();
1126
1416
  // setTimeoutSpy = sinon.spy(clock, 'setTimeout');
1127
- webex.meetings.meetingInfo.fetchMeetingInfo = sinon.stub().returns(Promise.resolve({
1128
- body: {
1129
- permissionToken: 'PT', meetingJoinUrl: 'meetingJoinUrl'
1130
- }
1131
- }));
1417
+ webex.meetings.meetingInfo.fetchMeetingInfo = sinon.stub().returns(
1418
+ Promise.resolve({
1419
+ body: {
1420
+ permissionToken: 'PT',
1421
+ meetingJoinUrl: 'meetingJoinUrl',
1422
+ },
1423
+ })
1424
+ );
1132
1425
 
1133
1426
  meeting = await webex.meetings.createMeeting('test destination', 'test type');
1134
1427
 
@@ -1136,37 +1429,37 @@ describe('plugin-meetings', () => {
1136
1429
  });
1137
1430
 
1138
1431
  it('triggers correct event when CONTROLS_ENTRY_EXIT_TONE_UPDATED emitted', async () => {
1139
- await meeting.locusInfo.emitScoped(
1140
- {},
1141
- LOCUSINFO.EVENTS.CONTROLS_ENTRY_EXIT_TONE_UPDATED,
1142
- {entryExitTone: 'foo'}
1143
- );
1432
+ await meeting.locusInfo.emitScoped({}, LOCUSINFO.EVENTS.CONTROLS_ENTRY_EXIT_TONE_UPDATED, {
1433
+ entryExitTone: 'foo',
1434
+ });
1144
1435
 
1145
1436
  assert.calledOnce(TriggerProxy.trigger);
1146
- assert.calledWith(TriggerProxy.trigger, sinon.match.instanceOf(Meeting),
1437
+ assert.calledWith(
1438
+ TriggerProxy.trigger,
1439
+ sinon.match.instanceOf(Meeting),
1147
1440
  {
1148
1441
  file: 'meeting/index',
1149
- function: 'setupLocusControlsListener'
1442
+ function: 'setupLocusControlsListener',
1150
1443
  },
1151
1444
  EVENT_TRIGGERS.MEETING_ENTRY_EXIT_TONE_UPDATE,
1152
- {entryExitTone: 'foo'});
1445
+ {entryExitTone: 'foo'}
1446
+ );
1153
1447
  });
1154
1448
 
1155
1449
  const checkSelfTrigger = async (inEvent, outEvent) => {
1156
- await meeting.locusInfo.emitScoped(
1157
- {},
1158
- inEvent,
1159
- {foo: 'bar'}
1160
- );
1450
+ await meeting.locusInfo.emitScoped({}, inEvent, {foo: 'bar'});
1161
1451
 
1162
1452
  assert.calledOnce(TriggerProxy.trigger);
1163
- assert.calledWith(TriggerProxy.trigger, sinon.match.instanceOf(Meeting),
1453
+ assert.calledWith(
1454
+ TriggerProxy.trigger,
1455
+ sinon.match.instanceOf(Meeting),
1164
1456
  {
1165
1457
  file: 'meeting/index',
1166
- function: 'setUpLocusInfoSelfListener'
1458
+ function: 'setUpLocusInfoSelfListener',
1167
1459
  },
1168
1460
  outEvent,
1169
- {payload: {foo: 'bar'}});
1461
+ {payload: {foo: 'bar'}}
1462
+ );
1170
1463
  };
1171
1464
 
1172
1465
  it('triggers correct event when SELF_CANNOT_VIEW_PARTICIPANT_LIST_CHANGE emitted', async () => {
@@ -1190,5 +1483,431 @@ describe('plugin-meetings', () => {
1190
1483
  );
1191
1484
  });
1192
1485
  });
1486
+
1487
+ describe('#isNeedHandleMainLocus', () => {
1488
+ let meeting;
1489
+ let newLocus;
1490
+ beforeEach(() => {
1491
+ meeting = {
1492
+ controls: {},
1493
+ self: {},
1494
+ };
1495
+ newLocus = {
1496
+ controls: {},
1497
+ self: {},
1498
+ }
1499
+ });
1500
+ afterEach(() => {
1501
+ sinon.restore();
1502
+ });
1503
+ it('check normal case will return true', () => {
1504
+ sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
1505
+ LoggerProxy.logger.log = sinon.stub();
1506
+ const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
1507
+ assert.equal(result, true);
1508
+ assert.calledWith(
1509
+ LoggerProxy.logger.log,
1510
+ 'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
1511
+ );
1512
+ });
1513
+
1514
+ it('check self joined and joined on this device, return true', () => {
1515
+ sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns(null);
1516
+ newLocus.self.state = 'JOINED';
1517
+ sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
1518
+
1519
+ LoggerProxy.logger.log = sinon.stub();
1520
+ const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
1521
+ assert.equal(result, true);
1522
+ assert.calledWith(
1523
+ LoggerProxy.logger.log,
1524
+ 'Meetings:index#isNeedHandleMainLocus --> self this device shown as JOINED in the main session'
1525
+ );
1526
+ });
1527
+
1528
+ it('if newLocus replaceAt time is expired, then return false', () => {
1529
+ sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({joinedWith: {replaces: [{
1530
+ replaceAt: '2023-03-27T02:17:02.506Z',
1531
+ }]}});
1532
+ newLocus.self.state = 'JOINED';
1533
+ sinon.stub(MeetingsUtil, 'joinedOnThisDevice').returns(true);
1534
+ sinon.stub(MeetingsUtil, 'getThisDevice').returns({
1535
+ replaces: [{
1536
+ replaceAt: '2023-03-27T02:17:01.506Z'
1537
+ }]
1538
+ })
1539
+
1540
+ LoggerProxy.logger.log = sinon.stub();
1541
+ const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
1542
+ assert.equal(result, false);
1543
+ assert.calledWith(
1544
+ LoggerProxy.logger.log,
1545
+ `Meetings:index#isNeedHandleMainLocus --> this is expired main joined status locus_dto replacedAt 2023-03-27T02:17:01.506Z bo replacedAt 2023-03-27T02:17:02.506Z`
1546
+ );
1547
+ });
1548
+
1549
+ it('check current is in breakout join with this device, return false', () => {
1550
+ sinon.stub(webex.meetings.meetingCollection, 'getActiveBreakoutLocus').returns({
1551
+ joinedWith: {
1552
+ correlationId: '111',
1553
+ },
1554
+ });
1555
+ newLocus.controls.breakout = {url: 'url'};
1556
+ meeting.correlationId = '111';
1557
+
1558
+ LoggerProxy.logger.log = sinon.stub();
1559
+ const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
1560
+ assert.equal(result, false);
1561
+ assert.calledWith(
1562
+ LoggerProxy.logger.log,
1563
+ `Meetings:index#isNeedHandleMainLocus --> there is active breakout session and joined on this device, and don't need to handle main session: url`
1564
+ );
1565
+ });
1566
+
1567
+ it('check self is moved and removed, return false', () => {
1568
+ webex.meetings.meetingCollection.getActiveBreakoutLocus = sinon.stub().returns(null);
1569
+ newLocus.self.state = 'LEFT';
1570
+ newLocus.self.reason = 'MOVED';
1571
+ newLocus.self.removed = true;
1572
+ LoggerProxy.logger.log = sinon.stub();
1573
+ const result = webex.meetings.isNeedHandleMainLocus(meeting, newLocus);
1574
+ assert.equal(result, false);
1575
+ assert.calledWith(
1576
+ LoggerProxy.logger.log,
1577
+ 'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status, not need to handle'
1578
+ );
1579
+ });
1580
+ });
1581
+
1582
+ describe('#isNeedHandleLocusDTO', () => {
1583
+ let meeting;
1584
+ let newLocus;
1585
+ beforeEach(() => {
1586
+ meeting = {
1587
+ controls: {},
1588
+ self: {},
1589
+ };
1590
+ newLocus = {
1591
+ controls: {},
1592
+ self: {},
1593
+ }
1594
+ });
1595
+ afterEach(() => {
1596
+ sinon.restore();
1597
+ });
1598
+ it('initial DTO , joined breakout session, return true', () => {
1599
+ newLocus.controls.breakout = {
1600
+ sessionType: 'BREAKOUT',
1601
+ };
1602
+ newLocus.self.state = 'JOINED';
1603
+ newLocus.fullState = {
1604
+ active: true,
1605
+ };
1606
+ LoggerProxy.logger.log = sinon.stub();
1607
+ const result = webex.meetings.isNeedHandleLocusDTO(null, newLocus);
1608
+ assert.equal(result, true);
1609
+ assert.calledWith(
1610
+ LoggerProxy.logger.log,
1611
+ `Meetings:index#isNeedHandleLocusDTO --> the first breakout session locusDTO active status: true`
1612
+ );
1613
+ });
1614
+ it('others go to check isNeedHandleMainLocus', () => {
1615
+ newLocus.controls.breakout = {
1616
+ sessionType: 'MAIN',
1617
+ };
1618
+ newLocus.self.state = 'JOINED';
1619
+
1620
+ LoggerProxy.logger.log = sinon.stub();
1621
+ const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
1622
+ assert.equal(result, true);
1623
+ assert.calledWith(
1624
+ LoggerProxy.logger.log,
1625
+ 'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
1626
+ );
1627
+ });
1628
+ it('joined breakout session, self status is moved, return false', () => {
1629
+ newLocus.controls.breakout = {
1630
+ sessionType: 'BREAKOUT',
1631
+ };
1632
+ newLocus.self.state = 'LEFT';
1633
+ newLocus.self.reason = 'MOVED';
1634
+
1635
+ LoggerProxy.logger.log = sinon.stub();
1636
+ const result = webex.meetings.isNeedHandleLocusDTO(meeting, newLocus);
1637
+ assert.equal(result, false);
1638
+ });
1639
+ });
1640
+
1641
+ describe('#getCorrespondingMeetingByLocus', () => {
1642
+ let locus;
1643
+ let mockReturnMeeting = {meeting: 'meeting1'};
1644
+ const mockGetByKey = (keyWillReturnMeeting) => {
1645
+ webex.meetings.meetingCollection.getByKey = sinon.stub().callsFake((key) => {
1646
+ if (key === keyWillReturnMeeting) {
1647
+ return mockReturnMeeting;
1648
+ }
1649
+ return null;
1650
+ });
1651
+ };
1652
+
1653
+ beforeEach(() => {
1654
+ locus = {
1655
+ controls: {},
1656
+ self: {
1657
+ callbackInfo: {
1658
+ callbackAddress: 'address1',
1659
+ }
1660
+ },
1661
+ info: {
1662
+ webExMeetingId: '123456',
1663
+ isUnifiedSpaceMeeting: false,
1664
+ },
1665
+ conversationUrl: 'conversationUrl1'
1666
+ };
1667
+
1668
+ sinon.stub(MeetingsUtil, 'checkForCorrelationId').returns('correlationId1');
1669
+ });
1670
+ afterEach(() => {
1671
+ sinon.restore();
1672
+ });
1673
+ it('check the calls when no meeting found in meetingCollection', () => {
1674
+ mockGetByKey();
1675
+ const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
1676
+ assert.isNull(result);
1677
+ assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
1678
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
1679
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
1680
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
1681
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'conversationUrl', 'conversationUrl1');
1682
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
1683
+ });
1684
+
1685
+ it('not try getByKey "conversationUrl" when isUnifiedSpaceMeeting is true', () => {
1686
+ mockGetByKey();
1687
+ locus.info.isUnifiedSpaceMeeting = true;
1688
+ const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
1689
+ assert.isNull(result);
1690
+ assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
1691
+ })
1692
+
1693
+ it('check the calls when meeting found by key: locusUrl', () => {
1694
+ mockGetByKey('locusUrl');
1695
+ const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
1696
+ assert.deepEqual(result, mockReturnMeeting);
1697
+ assert.callCount(webex.meetings.meetingCollection.getByKey, 1);
1698
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
1699
+ });
1700
+
1701
+ it('check the calls when meeting found by key: correlationId', () => {
1702
+ mockGetByKey('correlationId');
1703
+ const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
1704
+ assert.deepEqual(result, mockReturnMeeting);
1705
+ assert.callCount(webex.meetings.meetingCollection.getByKey, 2);
1706
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
1707
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
1708
+ });
1709
+
1710
+ it('check the calls when meeting found by key: sipUri', () => {
1711
+ mockGetByKey('sipUri');
1712
+ const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
1713
+ assert.deepEqual(result, mockReturnMeeting);
1714
+ assert.callCount(webex.meetings.meetingCollection.getByKey, 3);
1715
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
1716
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
1717
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
1718
+ });
1719
+
1720
+ it('check the calls when meeting found by key: conversationUrl', () => {
1721
+ mockGetByKey('conversationUrl');
1722
+ const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
1723
+ assert.deepEqual(result, mockReturnMeeting);
1724
+ assert.callCount(webex.meetings.meetingCollection.getByKey, 4);
1725
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
1726
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
1727
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
1728
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'conversationUrl', 'conversationUrl1');
1729
+ });
1730
+
1731
+ it('check the calls when meeting found by key: meetingNumber', () => {
1732
+ mockGetByKey('meetingNumber');
1733
+ const result = webex.meetings.getCorrespondingMeetingByLocus({locus, locusUrl: url1});
1734
+ assert.deepEqual(result, mockReturnMeeting);
1735
+ assert.callCount(webex.meetings.meetingCollection.getByKey, 5);
1736
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'locusUrl', url1);
1737
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'correlationId', 'correlationId1');
1738
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'sipUri', 'address1');
1739
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'conversationUrl', 'conversationUrl1');
1740
+ assert.calledWith(webex.meetings.meetingCollection.getByKey, 'meetingNumber', '123456');
1741
+ });
1742
+ });
1743
+
1744
+ describe('#sortLocusArrayToUpdate', () => {
1745
+ let lociArray;
1746
+ let mainLocus;
1747
+ let breakoutLocus;
1748
+ beforeEach(() => {
1749
+ mainLocus = {
1750
+ url: 'mainUrl1',
1751
+ controls: {
1752
+ breakout: {
1753
+ sessionType: 'MAIN',
1754
+ url: 'breakoutUnifiedUrl1'
1755
+ }
1756
+ }
1757
+ };
1758
+ breakoutLocus = {
1759
+ url: 'breakoutUrl1',
1760
+ controls: {
1761
+ breakout: {
1762
+ sessionType: 'BREAKOUT',
1763
+ url: 'breakoutUnifiedUrl1'
1764
+ }
1765
+ }
1766
+ };
1767
+ lociArray = [mainLocus, breakoutLocus];
1768
+
1769
+ sinon.stub(MeetingsUtil, 'isValidBreakoutLocus').callsFake((locus) => {
1770
+ return locus.url === 'breakoutUrl1';
1771
+ });
1772
+ });
1773
+ afterEach(() => {
1774
+ sinon.restore();
1775
+ });
1776
+
1777
+ it('if both main and breakout locus is in array for non-exist meeting, return main locus to create first', () => {
1778
+ webex.meetings.meetingCollection.getByKey = sinon.stub().returns(undefined);
1779
+ const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
1780
+ assert.deepEqual(result, [mainLocus]);
1781
+ assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, [breakoutLocus]);
1782
+ });
1783
+
1784
+ it('if both main and breakout locus is in array for an exist meeting, return all locus', () => {
1785
+ webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
1786
+ const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
1787
+ assert.deepEqual(result, [mainLocus, breakoutLocus]);
1788
+ assert.deepEqual(webex.meetings.breakoutLocusForHandleLater, []);
1789
+ });
1790
+
1791
+ it('if the breakout locus has no associated main locus, return all', () => {
1792
+ webex.meetings.meetingCollection.getByKey = sinon.stub().returns({});
1793
+ breakoutLocus.controls.breakout.url = 'testUrl';
1794
+ const result = webex.meetings.sortLocusArrayToUpdate(lociArray);
1795
+ assert.deepEqual(result, [mainLocus, breakoutLocus]);
1796
+ });
1797
+ });
1798
+
1799
+ describe('#checkHandleBreakoutLocus', () => {
1800
+ let breakoutLocus;
1801
+ beforeEach(() => {
1802
+ breakoutLocus = {
1803
+ url: 'breakoutUrl1',
1804
+ controls: {
1805
+ breakout: {
1806
+ sessionType: 'BREAKOUT',
1807
+ url: 'breakoutUnifiedUrl1',
1808
+ }
1809
+ }
1810
+ };
1811
+
1812
+ webex.meetings.handleLocusEvent = sinon.stub();
1813
+ });
1814
+ afterEach(() => {
1815
+ sinon.restore();
1816
+ });
1817
+ it('do nothing if new created locus is null/no cached breakouts for updating', () => {
1818
+ webex.meetings.checkHandleBreakoutLocus(null);
1819
+ webex.meetings.breakoutLocusForHandleLater = null;
1820
+ webex.meetings.checkHandleBreakoutLocus({});
1821
+ webex.meetings.breakoutLocusForHandleLater = [];
1822
+ webex.meetings.checkHandleBreakoutLocus({});
1823
+ assert.notCalled(webex.meetings.handleLocusEvent);
1824
+ });
1825
+
1826
+ it('do nothing if new created locus is breakout locus', () => {
1827
+ webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
1828
+ webex.meetings.checkHandleBreakoutLocus(breakoutLocus);
1829
+ assert.notCalled(webex.meetings.handleLocusEvent);
1830
+ });
1831
+
1832
+ it('do nothing if no cached locus is associated with the new created locus', () => {
1833
+ webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
1834
+ webex.meetings.checkHandleBreakoutLocus({
1835
+ controls: {
1836
+ breakout: {
1837
+ sessionType: 'MAIN',
1838
+ url: 'breakoutUnifiedUrl2',
1839
+ }
1840
+ }
1841
+ });
1842
+ assert.notCalled(webex.meetings.handleLocusEvent);
1843
+ });
1844
+
1845
+ it('update the cached breakout locus which associate the new created locus', () => {
1846
+ webex.meetings.breakoutLocusForHandleLater = [breakoutLocus];
1847
+ webex.meetings.checkHandleBreakoutLocus({
1848
+ controls: {
1849
+ breakout: {
1850
+ sessionType: 'MAIN',
1851
+ url: 'breakoutUnifiedUrl1',
1852
+ }
1853
+ }
1854
+ });
1855
+ assert.calledWith(webex.meetings.handleLocusEvent, {locus: breakoutLocus, locusUrl: breakoutLocus.url});
1856
+ });
1857
+ });
1858
+
1859
+ describe('#getAnalyzerMetricsPrePayload', () => {
1860
+ it('userType & userLogin & environment testing for CA data', async () => {
1861
+ const FAKE_LOCUS_MEETING = {
1862
+ conversationUrl: 'locusConvURL',
1863
+ url: 'locusUrl',
1864
+ info: {
1865
+ webExMeetingId: 'locusMeetingId',
1866
+ sipUri: 'locusSipUri',
1867
+ owner: 'locusOwner',
1868
+ },
1869
+ meeting: {
1870
+ startTime: "",
1871
+ },
1872
+ fullState: {
1873
+ active: false,
1874
+ },
1875
+ };
1876
+
1877
+ const meeting = await webex.meetings.createMeeting(
1878
+ FAKE_LOCUS_MEETING,
1879
+ 'test type',
1880
+ true
1881
+ );
1882
+ meeting.roles = ['MODERATOR','COHOST','ATTENDEE'];
1883
+ meeting.guest = true;
1884
+ const options = {
1885
+ event: 'event',
1886
+ trackingId: 'trackingId',
1887
+ locus: {},
1888
+ mediaConnections: null,
1889
+ errors: {}
1890
+ };
1891
+ webex.internal.services.get = sinon.stub();
1892
+ webex.canAuthorize = true;
1893
+ webex.credentials = {isUnverifiedGuest: true};
1894
+ meeting.getAnalyzerMetricsPrePayload(options);
1895
+ assert.equal(options.userType, 'host');
1896
+ assert.equal(options.loginType, 'unverified-guest');
1897
+ meeting.roles = ['COHOST','ATTENDEE'];
1898
+ meeting.guest = false;
1899
+ webex.canAuthorize = true;
1900
+ webex.credentials = {isUnverifiedGuest: false};
1901
+ meeting.getAnalyzerMetricsPrePayload(options);
1902
+ assert.equal(options.userType, 'cohost');
1903
+ assert.equal(options.loginType, 'login-ci');
1904
+ meeting.roles = ['ATTENDEE'];
1905
+ meeting.getAnalyzerMetricsPrePayload(options);
1906
+ assert.equal(options.userType, 'attendee');
1907
+ meeting.environment = "prod";
1908
+ meeting.getAnalyzerMetricsPrePayload(options);
1909
+ assert.equal(options.environment, 'prod');
1910
+ });
1911
+ });
1193
1912
  });
1194
1913
  });