@webex/plugin-meetings 3.0.0-stream-classes.5 → 3.0.0

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 (465) hide show
  1. package/.eslintrc.js +6 -0
  2. package/README.md +12 -0
  3. package/babel.config.js +3 -0
  4. package/dist/annotation/constants.js +12 -20
  5. package/dist/annotation/constants.js.map +1 -1
  6. package/dist/annotation/index.js +25 -10
  7. package/dist/annotation/index.js.map +1 -1
  8. package/dist/breakouts/breakout.js +2 -3
  9. package/dist/breakouts/breakout.js.map +1 -1
  10. package/dist/breakouts/collection.js +1 -2
  11. package/dist/breakouts/collection.js.map +1 -1
  12. package/dist/breakouts/edit-lock-error.js +1 -2
  13. package/dist/breakouts/edit-lock-error.js.map +1 -1
  14. package/dist/breakouts/events.js +1 -2
  15. package/dist/breakouts/events.js.map +1 -1
  16. package/dist/breakouts/index.js +13 -14
  17. package/dist/breakouts/index.js.map +1 -1
  18. package/dist/breakouts/request.js +1 -2
  19. package/dist/breakouts/request.js.map +1 -1
  20. package/dist/breakouts/utils.js +3 -6
  21. package/dist/breakouts/utils.js.map +1 -1
  22. package/dist/common/browser-detection.js +2 -3
  23. package/dist/common/browser-detection.js.map +1 -1
  24. package/dist/common/collection.js +3 -4
  25. package/dist/common/collection.js.map +1 -1
  26. package/dist/common/config.js +1 -2
  27. package/dist/common/config.js.map +1 -1
  28. package/dist/common/errors/captcha-error.js +1 -2
  29. package/dist/common/errors/captcha-error.js.map +1 -1
  30. package/dist/common/errors/intent-to-join.js +1 -2
  31. package/dist/common/errors/intent-to-join.js.map +1 -1
  32. package/dist/common/errors/join-meeting.js +1 -2
  33. package/dist/common/errors/join-meeting.js.map +1 -1
  34. package/dist/common/errors/media.js +1 -2
  35. package/dist/common/errors/media.js.map +1 -1
  36. package/dist/common/errors/no-meeting-info.d.ts +14 -0
  37. package/dist/common/errors/no-meeting-info.js +50 -0
  38. package/dist/common/errors/no-meeting-info.js.map +1 -0
  39. package/dist/common/errors/parameter.js +3 -4
  40. package/dist/common/errors/parameter.js.map +1 -1
  41. package/dist/common/errors/password-error.js +1 -2
  42. package/dist/common/errors/password-error.js.map +1 -1
  43. package/dist/common/errors/permission.js +1 -2
  44. package/dist/common/errors/permission.js.map +1 -1
  45. package/dist/common/errors/reclaim-host-role-errors.d.ts +60 -0
  46. package/dist/common/errors/reclaim-host-role-errors.js +154 -0
  47. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  48. package/dist/common/errors/reconnection-in-progress.js +1 -2
  49. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  50. package/dist/common/errors/reconnection.js +1 -2
  51. package/dist/common/errors/reconnection.js.map +1 -1
  52. package/dist/common/errors/stats.js +1 -2
  53. package/dist/common/errors/stats.js.map +1 -1
  54. package/dist/{types/common → common}/errors/webex-errors.d.ts +13 -1
  55. package/dist/common/errors/webex-errors.js +35 -16
  56. package/dist/common/errors/webex-errors.js.map +1 -1
  57. package/dist/common/errors/webex-meetings-error.js +1 -2
  58. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  59. package/dist/common/events/events-scope.js +1 -2
  60. package/dist/common/events/events-scope.js.map +1 -1
  61. package/dist/common/events/events.js +1 -2
  62. package/dist/common/events/events.js.map +1 -1
  63. package/dist/common/events/trigger-proxy.js +1 -2
  64. package/dist/common/events/trigger-proxy.js.map +1 -1
  65. package/dist/common/events/util.js +1 -2
  66. package/dist/common/events/util.js.map +1 -1
  67. package/dist/common/logs/logger-config.js +1 -2
  68. package/dist/common/logs/logger-config.js.map +1 -1
  69. package/dist/common/logs/logger-proxy.js +1 -2
  70. package/dist/common/logs/logger-proxy.js.map +1 -1
  71. package/dist/{types/common → common}/logs/request.d.ts +3 -1
  72. package/dist/common/logs/request.js +8 -5
  73. package/dist/common/logs/request.js.map +1 -1
  74. package/dist/common/queue.js +2 -4
  75. package/dist/common/queue.js.map +1 -1
  76. package/dist/{types/config.d.ts → config.d.ts} +1 -1
  77. package/dist/config.js +3 -3
  78. package/dist/config.js.map +1 -1
  79. package/dist/{types/constants.d.ts → constants.d.ts} +71 -15
  80. package/dist/constants.js +252 -371
  81. package/dist/constants.js.map +1 -1
  82. package/dist/controls-options-manager/constants.js +3 -6
  83. package/dist/controls-options-manager/constants.js.map +1 -1
  84. package/dist/controls-options-manager/enums.js +7 -10
  85. package/dist/controls-options-manager/enums.js.map +1 -1
  86. package/dist/controls-options-manager/index.js +27 -32
  87. package/dist/controls-options-manager/index.js.map +1 -1
  88. package/dist/controls-options-manager/util.js +1 -2
  89. package/dist/controls-options-manager/util.js.map +1 -1
  90. package/dist/index.js +8 -5
  91. package/dist/index.js.map +1 -1
  92. package/dist/interceptors/index.d.ts +2 -0
  93. package/dist/interceptors/index.js +15 -0
  94. package/dist/interceptors/index.js.map +1 -0
  95. package/dist/interceptors/locusRetry.d.ts +27 -0
  96. package/dist/interceptors/locusRetry.js +94 -0
  97. package/dist/interceptors/locusRetry.js.map +1 -0
  98. package/dist/interpretation/collection.js +1 -2
  99. package/dist/interpretation/collection.js.map +1 -1
  100. package/dist/interpretation/index.js +2 -3
  101. package/dist/interpretation/index.js.map +1 -1
  102. package/dist/interpretation/siLanguage.js +2 -3
  103. package/dist/interpretation/siLanguage.js.map +1 -1
  104. package/dist/locus-info/controlsUtils.js +12 -13
  105. package/dist/locus-info/controlsUtils.js.map +1 -1
  106. package/dist/locus-info/embeddedAppsUtils.js +3 -4
  107. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  108. package/dist/locus-info/fullState.js +1 -2
  109. package/dist/locus-info/fullState.js.map +1 -1
  110. package/dist/locus-info/hostUtils.js +1 -2
  111. package/dist/locus-info/hostUtils.js.map +1 -1
  112. package/dist/{types/locus-info → locus-info}/index.d.ts +1 -1
  113. package/dist/locus-info/index.js +38 -37
  114. package/dist/locus-info/index.js.map +1 -1
  115. package/dist/locus-info/infoUtils.js +3 -4
  116. package/dist/locus-info/infoUtils.js.map +1 -1
  117. package/dist/locus-info/mediaSharesUtils.js +16 -3
  118. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  119. package/dist/{types/locus-info → locus-info}/parser.d.ts +3 -2
  120. package/dist/locus-info/parser.js +43 -31
  121. package/dist/locus-info/parser.js.map +1 -1
  122. package/dist/locus-info/selfUtils.js +7 -6
  123. package/dist/locus-info/selfUtils.js.map +1 -1
  124. package/dist/media/index.js +15 -10
  125. package/dist/media/index.js.map +1 -1
  126. package/dist/media/properties.js +16 -7
  127. package/dist/media/properties.js.map +1 -1
  128. package/dist/media/util.js +1 -2
  129. package/dist/media/util.js.map +1 -1
  130. package/dist/mediaQualityMetrics/config.d.ts +241 -0
  131. package/dist/mediaQualityMetrics/config.js +135 -339
  132. package/dist/mediaQualityMetrics/config.js.map +1 -1
  133. package/dist/{types/meeting → meeting}/in-meeting-actions.d.ts +4 -0
  134. package/dist/meeting/in-meeting-actions.js +18 -2
  135. package/dist/meeting/in-meeting-actions.js.map +1 -1
  136. package/dist/{types/meeting → meeting}/index.d.ts +318 -45
  137. package/dist/meeting/index.js +2620 -1405
  138. package/dist/meeting/index.js.map +1 -1
  139. package/dist/meeting/locusMediaRequest.js +4 -5
  140. package/dist/meeting/locusMediaRequest.js.map +1 -1
  141. package/dist/meeting/muteState.js +2 -4
  142. package/dist/meeting/muteState.js.map +1 -1
  143. package/dist/{types/meeting → meeting}/request.d.ts +2 -0
  144. package/dist/meeting/request.js +46 -31
  145. package/dist/meeting/request.js.map +1 -1
  146. package/dist/meeting/state.js +1 -2
  147. package/dist/meeting/state.js.map +1 -1
  148. package/dist/{types/meeting → meeting}/util.d.ts +17 -0
  149. package/dist/meeting/util.js +83 -10
  150. package/dist/meeting/util.js.map +1 -1
  151. package/dist/meeting/voicea-meeting.d.ts +16 -0
  152. package/dist/meeting/voicea-meeting.js +169 -0
  153. package/dist/meeting/voicea-meeting.js.map +1 -0
  154. package/dist/meeting-info/collection.js +3 -4
  155. package/dist/meeting-info/collection.js.map +1 -1
  156. package/dist/{types/meeting-info → meeting-info}/index.d.ts +7 -0
  157. package/dist/meeting-info/index.js +53 -27
  158. package/dist/meeting-info/index.js.map +1 -1
  159. package/dist/{types/meeting-info → meeting-info}/meeting-info-v2.d.ts +1 -0
  160. package/dist/meeting-info/meeting-info-v2.js +52 -33
  161. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  162. package/dist/meeting-info/request.js +1 -2
  163. package/dist/meeting-info/request.js.map +1 -1
  164. package/dist/meeting-info/util.js +8 -8
  165. package/dist/meeting-info/util.js.map +1 -1
  166. package/dist/meeting-info/utilv2.js +12 -9
  167. package/dist/meeting-info/utilv2.js.map +1 -1
  168. package/dist/{types/meetings → meetings}/collection.d.ts +9 -0
  169. package/dist/meetings/collection.js +21 -5
  170. package/dist/meetings/collection.js.map +1 -1
  171. package/dist/{types/meetings → meetings}/index.d.ts +45 -16
  172. package/dist/meetings/index.js +166 -74
  173. package/dist/meetings/index.js.map +1 -1
  174. package/dist/meetings/request.js +2 -3
  175. package/dist/meetings/request.js.map +1 -1
  176. package/dist/meetings/util.js +3 -10
  177. package/dist/meetings/util.js.map +1 -1
  178. package/dist/{types/member → member}/index.d.ts +1 -0
  179. package/dist/member/index.js +10 -3
  180. package/dist/member/index.js.map +1 -1
  181. package/dist/member/member.types.d.ts +11 -0
  182. package/dist/member/member.types.js +17 -0
  183. package/dist/member/member.types.js.map +1 -0
  184. package/dist/member/types.js +6 -8
  185. package/dist/member/types.js.map +1 -1
  186. package/dist/member/util.js +12 -2
  187. package/dist/member/util.js.map +1 -1
  188. package/dist/members/collection.js +1 -2
  189. package/dist/members/collection.js.map +1 -1
  190. package/dist/members/index.js +25 -8
  191. package/dist/members/index.js.map +1 -1
  192. package/dist/members/request.js +2 -3
  193. package/dist/members/request.js.map +1 -1
  194. package/dist/{types/members → members}/types.d.ts +1 -0
  195. package/dist/members/types.js +3 -4
  196. package/dist/members/types.js.map +1 -1
  197. package/dist/{types/members → members}/util.d.ts +6 -1
  198. package/dist/members/util.js +18 -8
  199. package/dist/members/util.js.map +1 -1
  200. package/dist/{types/metrics → metrics}/constants.d.ts +12 -0
  201. package/dist/metrics/constants.js +14 -3
  202. package/dist/metrics/constants.js.map +1 -1
  203. package/dist/metrics/index.js +3 -2
  204. package/dist/metrics/index.js.map +1 -1
  205. package/dist/multistream/mediaRequestManager.js +9 -11
  206. package/dist/multistream/mediaRequestManager.js.map +1 -1
  207. package/dist/multistream/receiveSlot.js +3 -5
  208. package/dist/multistream/receiveSlot.js.map +1 -1
  209. package/dist/multistream/receiveSlotManager.js +7 -9
  210. package/dist/multistream/receiveSlotManager.js.map +1 -1
  211. package/dist/multistream/remoteMedia.js +3 -5
  212. package/dist/multistream/remoteMedia.js.map +1 -1
  213. package/dist/multistream/remoteMediaGroup.js +7 -6
  214. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  215. package/dist/multistream/remoteMediaManager.js +28 -27
  216. package/dist/multistream/remoteMediaManager.js.map +1 -1
  217. package/dist/multistream/sendSlotManager.js +9 -6
  218. package/dist/multistream/sendSlotManager.js.map +1 -1
  219. package/dist/networkQualityMonitor/index.js +1 -2
  220. package/dist/networkQualityMonitor/index.js.map +1 -1
  221. package/dist/personal-meeting-room/index.js +2 -3
  222. package/dist/personal-meeting-room/index.js.map +1 -1
  223. package/dist/personal-meeting-room/request.js +2 -3
  224. package/dist/personal-meeting-room/request.js.map +1 -1
  225. package/dist/personal-meeting-room/util.js +1 -2
  226. package/dist/personal-meeting-room/util.js.map +1 -1
  227. package/dist/reachability/clusterReachability.d.ts +109 -0
  228. package/dist/reachability/clusterReachability.js +357 -0
  229. package/dist/reachability/clusterReachability.js.map +1 -0
  230. package/dist/reachability/index.d.ts +105 -0
  231. package/dist/reachability/index.js +279 -436
  232. package/dist/reachability/index.js.map +1 -1
  233. package/dist/reachability/request.js +14 -11
  234. package/dist/reachability/request.js.map +1 -1
  235. package/dist/reachability/util.d.ts +8 -0
  236. package/dist/reachability/util.js +29 -0
  237. package/dist/reachability/util.js.map +1 -0
  238. package/dist/reactions/constants.js +1 -2
  239. package/dist/reactions/constants.js.map +1 -1
  240. package/dist/reactions/reactions.js +2 -4
  241. package/dist/reactions/reactions.js.map +1 -1
  242. package/dist/reactions/reactions.type.js +6 -8
  243. package/dist/reactions/reactions.type.js.map +1 -1
  244. package/dist/{types/reconnection-manager → reconnection-manager}/index.d.ts +10 -0
  245. package/dist/reconnection-manager/index.js +129 -106
  246. package/dist/reconnection-manager/index.js.map +1 -1
  247. package/dist/recording-controller/enums.js +4 -5
  248. package/dist/recording-controller/enums.js.map +1 -1
  249. package/dist/recording-controller/index.js +43 -51
  250. package/dist/recording-controller/index.js.map +1 -1
  251. package/dist/recording-controller/util.js +1 -2
  252. package/dist/recording-controller/util.js.map +1 -1
  253. package/dist/{types/roap → roap}/index.d.ts +2 -1
  254. package/dist/roap/index.js +59 -28
  255. package/dist/roap/index.js.map +1 -1
  256. package/dist/roap/request.js +14 -22
  257. package/dist/roap/request.js.map +1 -1
  258. package/dist/{types/roap → roap}/turnDiscovery.d.ts +21 -4
  259. package/dist/roap/turnDiscovery.js +182 -89
  260. package/dist/roap/turnDiscovery.js.map +1 -1
  261. package/dist/rtcMetrics/constants.js +1 -2
  262. package/dist/rtcMetrics/constants.js.map +1 -1
  263. package/dist/{types/rtcMetrics → rtcMetrics}/index.d.ts +15 -1
  264. package/dist/rtcMetrics/index.js +72 -12
  265. package/dist/rtcMetrics/index.js.map +1 -1
  266. package/dist/statsAnalyzer/global.js +1 -2
  267. package/dist/statsAnalyzer/global.js.map +1 -1
  268. package/dist/{types/statsAnalyzer → statsAnalyzer}/index.d.ts +28 -11
  269. package/dist/statsAnalyzer/index.js +371 -318
  270. package/dist/statsAnalyzer/index.js.map +1 -1
  271. package/dist/statsAnalyzer/mqaUtil.d.ts +48 -0
  272. package/dist/statsAnalyzer/mqaUtil.js +295 -162
  273. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  274. package/dist/transcription/index.js +1 -2
  275. package/dist/transcription/index.js.map +1 -1
  276. package/dist/webinar/collection.d.ts +16 -0
  277. package/dist/webinar/collection.js +43 -0
  278. package/dist/webinar/collection.js.map +1 -0
  279. package/dist/webinar/index.d.ts +5 -0
  280. package/dist/webinar/index.js +68 -0
  281. package/dist/webinar/index.js.map +1 -0
  282. package/jest.config.js +3 -0
  283. package/package.json +44 -24
  284. package/process +1 -0
  285. package/src/common/errors/no-meeting-info.ts +24 -0
  286. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  287. package/src/common/errors/webex-errors.ts +19 -2
  288. package/src/common/logs/request.ts +5 -1
  289. package/src/config.ts +3 -5
  290. package/src/constants.ts +77 -8
  291. package/src/index.ts +4 -0
  292. package/src/interceptors/index.ts +3 -0
  293. package/src/interceptors/locusRetry.ts +67 -0
  294. package/src/locus-info/index.ts +19 -14
  295. package/src/locus-info/mediaSharesUtils.ts +16 -0
  296. package/src/locus-info/parser.ts +40 -21
  297. package/src/media/index.ts +8 -6
  298. package/src/media/properties.ts +17 -2
  299. package/src/mediaQualityMetrics/config.ts +103 -238
  300. package/src/meeting/in-meeting-actions.ts +8 -0
  301. package/src/meeting/index.ts +1664 -642
  302. package/src/meeting/request.ts +18 -0
  303. package/src/meeting/util.ts +102 -1
  304. package/src/meeting/voicea-meeting.ts +122 -0
  305. package/src/meeting-info/index.ts +47 -20
  306. package/src/meeting-info/meeting-info-v2.ts +32 -16
  307. package/src/meeting-info/util.ts +12 -9
  308. package/src/meeting-info/utilv2.ts +25 -15
  309. package/src/meetings/collection.ts +13 -0
  310. package/src/meetings/index.ts +112 -31
  311. package/src/meetings/util.ts +2 -8
  312. package/src/member/index.ts +9 -1
  313. package/src/member/member.types.ts +13 -0
  314. package/src/member/util.ts +14 -0
  315. package/src/members/index.ts +29 -2
  316. package/src/members/types.ts +1 -0
  317. package/src/members/util.ts +15 -1
  318. package/src/metrics/constants.ts +12 -0
  319. package/src/reachability/clusterReachability.ts +320 -0
  320. package/src/reachability/index.ts +221 -382
  321. package/src/reachability/request.ts +1 -1
  322. package/src/reachability/util.ts +24 -0
  323. package/src/reconnection-manager/index.ts +87 -83
  324. package/src/roap/index.ts +60 -24
  325. package/src/roap/request.ts +4 -17
  326. package/src/roap/turnDiscovery.ts +112 -39
  327. package/src/rtcMetrics/index.ts +71 -5
  328. package/src/statsAnalyzer/index.ts +430 -427
  329. package/src/statsAnalyzer/mqaUtil.ts +317 -168
  330. package/src/webinar/collection.ts +31 -0
  331. package/src/webinar/index.ts +62 -0
  332. package/test/integration/spec/journey.js +12 -12
  333. package/test/integration/spec/space-meeting.js +1 -1
  334. package/test/unit/spec/breakouts/breakout.ts +2 -1
  335. package/test/unit/spec/breakouts/index.ts +7 -4
  336. package/test/unit/spec/interceptors/locusRetry.ts +131 -0
  337. package/test/unit/spec/locus-info/index.js +88 -12
  338. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  339. package/test/unit/spec/locus-info/mediaSharesUtils.ts +10 -0
  340. package/test/unit/spec/locus-info/parser.js +54 -13
  341. package/test/unit/spec/locus-info/selfUtils.js +1 -1
  342. package/test/unit/spec/media/index.ts +25 -4
  343. package/test/unit/spec/media/properties.ts +2 -2
  344. package/test/unit/spec/meeting/in-meeting-actions.ts +4 -0
  345. package/test/unit/spec/meeting/index.js +4388 -1382
  346. package/test/unit/spec/meeting/request.js +63 -12
  347. package/test/unit/spec/meeting/utils.js +145 -10
  348. package/test/unit/spec/meeting/voicea-meeting.ts +266 -0
  349. package/test/unit/spec/meeting-info/index.js +180 -61
  350. package/test/unit/spec/meeting-info/meetinginfov2.js +216 -68
  351. package/test/unit/spec/meetings/collection.js +12 -0
  352. package/test/unit/spec/meetings/index.js +674 -193
  353. package/test/unit/spec/meetings/utils.js +35 -12
  354. package/test/unit/spec/member/index.js +8 -7
  355. package/test/unit/spec/member/util.js +32 -0
  356. package/test/unit/spec/members/index.js +130 -17
  357. package/test/unit/spec/members/utils.js +26 -0
  358. package/test/unit/spec/metrics/index.js +1 -2
  359. package/test/unit/spec/multistream/mediaRequestManager.ts +1 -0
  360. package/test/unit/spec/reachability/clusterReachability.ts +279 -0
  361. package/test/unit/spec/reachability/index.ts +505 -135
  362. package/test/unit/spec/reachability/util.ts +40 -0
  363. package/test/unit/spec/reconnection-manager/index.js +74 -17
  364. package/test/unit/spec/recording-controller/index.js +0 -1
  365. package/test/unit/spec/roap/index.ts +181 -61
  366. package/test/unit/spec/roap/request.ts +27 -3
  367. package/test/unit/spec/roap/turnDiscovery.ts +363 -102
  368. package/test/unit/spec/rtcMetrics/index.ts +57 -3
  369. package/test/unit/spec/stats-analyzer/index.js +1225 -12
  370. package/test/unit/spec/webinar/collection.ts +13 -0
  371. package/test/unit/spec/webinar/index.ts +60 -0
  372. package/test/utils/webex-test-users.js +12 -4
  373. package/dist/types/mediaQualityMetrics/config.d.ts +0 -365
  374. package/dist/types/reachability/index.d.ts +0 -152
  375. package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -24
  376. /package/dist/{types/annotation → annotation}/annotation.types.d.ts +0 -0
  377. /package/dist/{types/annotation → annotation}/constants.d.ts +0 -0
  378. /package/dist/{types/annotation → annotation}/index.d.ts +0 -0
  379. /package/dist/{types/breakouts → breakouts}/breakout.d.ts +0 -0
  380. /package/dist/{types/breakouts → breakouts}/collection.d.ts +0 -0
  381. /package/dist/{types/breakouts → breakouts}/edit-lock-error.d.ts +0 -0
  382. /package/dist/{types/breakouts → breakouts}/events.d.ts +0 -0
  383. /package/dist/{types/breakouts → breakouts}/index.d.ts +0 -0
  384. /package/dist/{types/breakouts → breakouts}/request.d.ts +0 -0
  385. /package/dist/{types/breakouts → breakouts}/utils.d.ts +0 -0
  386. /package/dist/{types/common → common}/browser-detection.d.ts +0 -0
  387. /package/dist/{types/common → common}/collection.d.ts +0 -0
  388. /package/dist/{types/common → common}/config.d.ts +0 -0
  389. /package/dist/{types/common → common}/errors/captcha-error.d.ts +0 -0
  390. /package/dist/{types/common → common}/errors/intent-to-join.d.ts +0 -0
  391. /package/dist/{types/common → common}/errors/join-meeting.d.ts +0 -0
  392. /package/dist/{types/common → common}/errors/media.d.ts +0 -0
  393. /package/dist/{types/common → common}/errors/parameter.d.ts +0 -0
  394. /package/dist/{types/common → common}/errors/password-error.d.ts +0 -0
  395. /package/dist/{types/common → common}/errors/permission.d.ts +0 -0
  396. /package/dist/{types/common → common}/errors/reconnection-in-progress.d.ts +0 -0
  397. /package/dist/{types/common → common}/errors/reconnection.d.ts +0 -0
  398. /package/dist/{types/common → common}/errors/stats.d.ts +0 -0
  399. /package/dist/{types/common → common}/errors/webex-meetings-error.d.ts +0 -0
  400. /package/dist/{types/common → common}/events/events-scope.d.ts +0 -0
  401. /package/dist/{types/common → common}/events/events.d.ts +0 -0
  402. /package/dist/{types/common → common}/events/trigger-proxy.d.ts +0 -0
  403. /package/dist/{types/common → common}/events/util.d.ts +0 -0
  404. /package/dist/{types/common → common}/logs/logger-config.d.ts +0 -0
  405. /package/dist/{types/common → common}/logs/logger-proxy.d.ts +0 -0
  406. /package/dist/{types/common → common}/queue.d.ts +0 -0
  407. /package/dist/{types/controls-options-manager → controls-options-manager}/constants.d.ts +0 -0
  408. /package/dist/{types/controls-options-manager → controls-options-manager}/enums.d.ts +0 -0
  409. /package/dist/{types/controls-options-manager → controls-options-manager}/index.d.ts +0 -0
  410. /package/dist/{types/controls-options-manager → controls-options-manager}/types.d.ts +0 -0
  411. /package/dist/{types/controls-options-manager → controls-options-manager}/util.d.ts +0 -0
  412. /package/dist/{types/index.d.ts → index.d.ts} +0 -0
  413. /package/dist/{types/interpretation → interpretation}/collection.d.ts +0 -0
  414. /package/dist/{types/interpretation → interpretation}/index.d.ts +0 -0
  415. /package/dist/{types/interpretation → interpretation}/siLanguage.d.ts +0 -0
  416. /package/dist/{types/locus-info → locus-info}/controlsUtils.d.ts +0 -0
  417. /package/dist/{types/locus-info → locus-info}/embeddedAppsUtils.d.ts +0 -0
  418. /package/dist/{types/locus-info → locus-info}/fullState.d.ts +0 -0
  419. /package/dist/{types/locus-info → locus-info}/hostUtils.d.ts +0 -0
  420. /package/dist/{types/locus-info → locus-info}/infoUtils.d.ts +0 -0
  421. /package/dist/{types/locus-info → locus-info}/mediaSharesUtils.d.ts +0 -0
  422. /package/dist/{types/locus-info → locus-info}/selfUtils.d.ts +0 -0
  423. /package/dist/{types/media → media}/index.d.ts +0 -0
  424. /package/dist/{types/media → media}/properties.d.ts +0 -0
  425. /package/dist/{types/media → media}/util.d.ts +0 -0
  426. /package/dist/{types/meeting → meeting}/locusMediaRequest.d.ts +0 -0
  427. /package/dist/{types/meeting → meeting}/muteState.d.ts +0 -0
  428. /package/dist/{types/meeting → meeting}/request.type.d.ts +0 -0
  429. /package/dist/{types/meeting → meeting}/state.d.ts +0 -0
  430. /package/dist/{types/meeting-info → meeting-info}/collection.d.ts +0 -0
  431. /package/dist/{types/meeting-info → meeting-info}/request.d.ts +0 -0
  432. /package/dist/{types/meeting-info → meeting-info}/util.d.ts +0 -0
  433. /package/dist/{types/meeting-info → meeting-info}/utilv2.d.ts +0 -0
  434. /package/dist/{types/meetings → meetings}/meetings.types.d.ts +0 -0
  435. /package/dist/{types/meetings → meetings}/request.d.ts +0 -0
  436. /package/dist/{types/meetings → meetings}/util.d.ts +0 -0
  437. /package/dist/{types/member → member}/types.d.ts +0 -0
  438. /package/dist/{types/member → member}/util.d.ts +0 -0
  439. /package/dist/{types/members → members}/collection.d.ts +0 -0
  440. /package/dist/{types/members → members}/index.d.ts +0 -0
  441. /package/dist/{types/members → members}/request.d.ts +0 -0
  442. /package/dist/{types/metrics → metrics}/index.d.ts +0 -0
  443. /package/dist/{types/multistream → multistream}/mediaRequestManager.d.ts +0 -0
  444. /package/dist/{types/multistream → multistream}/receiveSlot.d.ts +0 -0
  445. /package/dist/{types/multistream → multistream}/receiveSlotManager.d.ts +0 -0
  446. /package/dist/{types/multistream → multistream}/remoteMedia.d.ts +0 -0
  447. /package/dist/{types/multistream → multistream}/remoteMediaGroup.d.ts +0 -0
  448. /package/dist/{types/multistream → multistream}/remoteMediaManager.d.ts +0 -0
  449. /package/dist/{types/multistream → multistream}/sendSlotManager.d.ts +0 -0
  450. /package/dist/{types/networkQualityMonitor → networkQualityMonitor}/index.d.ts +0 -0
  451. /package/dist/{types/personal-meeting-room → personal-meeting-room}/index.d.ts +0 -0
  452. /package/dist/{types/personal-meeting-room → personal-meeting-room}/request.d.ts +0 -0
  453. /package/dist/{types/personal-meeting-room → personal-meeting-room}/util.d.ts +0 -0
  454. /package/dist/{types/reachability → reachability}/request.d.ts +0 -0
  455. /package/dist/{types/reactions → reactions}/constants.d.ts +0 -0
  456. /package/dist/{types/reactions → reactions}/reactions.d.ts +0 -0
  457. /package/dist/{types/reactions → reactions}/reactions.type.d.ts +0 -0
  458. /package/dist/{types/recording-controller → recording-controller}/enums.d.ts +0 -0
  459. /package/dist/{types/recording-controller → recording-controller}/index.d.ts +0 -0
  460. /package/dist/{types/recording-controller → recording-controller}/util.d.ts +0 -0
  461. /package/dist/{types/roap → roap}/request.d.ts +0 -0
  462. /package/dist/{types/rtcMetrics → rtcMetrics}/constants.d.ts +0 -0
  463. /package/dist/{types/statsAnalyzer → statsAnalyzer}/global.d.ts +0 -0
  464. /package/dist/{types/transcription → transcription}/index.d.ts +0 -0
  465. /package/test/unit/spec/locus-info/{selfConstant.js → lib/selfConstant.js} +0 -0
@@ -162,9 +162,24 @@ describe('plugin-meetings', () => {
162
162
  });
163
163
 
164
164
  describe("#handleRoapMercury", () => {
165
- it('it sends the correct behaviour metric', () => {
166
- const roapMessageReceived = sinon.stub();
167
- const envelope = {
165
+ let envelope;
166
+ let meetingCollection;
167
+ let roapMessageReceived;
168
+ let handleTurnDiscoveryResponse;
169
+ let meeting;
170
+
171
+ beforeEach(() => {
172
+ roapMessageReceived = sinon.stub();
173
+ handleTurnDiscoveryResponse = sinon.stub();
174
+
175
+ meeting = {
176
+ id: 'meeting-id',
177
+ roapMessageReceived,
178
+ roap: {
179
+ turnDiscovery: {handleTurnDiscoveryResponse}
180
+ }
181
+ };
182
+ envelope = {
168
183
  data: {
169
184
  message:{
170
185
  seq: "seq",
@@ -178,17 +193,12 @@ describe('plugin-meetings', () => {
178
193
  eventType: 'locus.message.roap',
179
194
  }
180
195
  };
181
- const meetingCollection = {
182
- getByKey: () => ({
183
- id: 'meeting-id',
184
- mediaProperties: {
185
- webrtcMediaConnection: {
186
- roapMessageReceived
187
- }
188
- }
189
- })
196
+ meetingCollection = {
197
+ getByKey: () => meeting
190
198
  };
199
+ });
191
200
 
201
+ it('it sends the correct behaviour metric', () => {
192
202
  MeetingsUtil.handleRoapMercury(envelope, meetingCollection);
193
203
  assert.calledWith(Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.ROAP_MERCURY_EVENT_RECEIVED, {
194
204
  correlation_id: 'correlationId',
@@ -207,6 +217,19 @@ describe('plugin-meetings', () => {
207
217
  })
208
218
 
209
219
  });
220
+
221
+ it('calls handleTurnDiscoveryResponse for TURN_DISCOVERY_RESPONSE', () => {
222
+ envelope.data.message.messageType = 'TURN_DISCOVERY_RESPONSE';
223
+ delete envelope.data.message.sdps;
224
+ MeetingsUtil.handleRoapMercury(envelope, meetingCollection);
225
+ assert.calledWith(meeting.roap.turnDiscovery.handleTurnDiscoveryResponse, {
226
+ seq: "seq",
227
+ messageType: 'TURN_DISCOVERY_RESPONSE',
228
+ errorType: 'errorType',
229
+ tieBreaker: 'tieBreaker',
230
+ errorCause: 'errorCause',
231
+ }, 'from mercury')
232
+ });
210
233
  })
211
234
  });
212
235
 
@@ -17,13 +17,7 @@ describe('member', () => {
17
17
  assert.exists(member.supportsInterpretation);
18
18
  assert.exists(member.supportsBreakouts);
19
19
  assert.exists(member.supportLiveAnnotation);
20
- });
21
-
22
- it('checks that processParticipant calls isHandRaised', () => {
23
- sinon.spy(MemberUtil, 'isHandRaised');
24
- member.processParticipant(participant);
25
-
26
- assert.calledOnceWithExactly(MemberUtil.isHandRaised, participant);
20
+ assert.exists(member.canReclaimHost);
27
21
  });
28
22
 
29
23
  describe('roles', () => {
@@ -49,6 +43,13 @@ describe('member', () => {
49
43
 
50
44
  assert.calledOnceWithExactly(MemberUtil.isHandRaised, participant);
51
45
  });
46
+
47
+ it('checks that processParticipant calls canReclaimHost', () => {
48
+ sinon.spy(MemberUtil, 'canReclaimHost');
49
+ member.processParticipant(participant);
50
+
51
+ assert.calledOnceWithExactly(MemberUtil.canReclaimHost, participant);
52
+ });
52
53
  })
53
54
 
54
55
  describe('#processMember', () => {
@@ -50,6 +50,38 @@ describe('plugin-meetings', () => {
50
50
  });
51
51
  });
52
52
 
53
+ describe('MemberUtil.canReclaimHost', () => {
54
+ it('throws error when there is no participant', () => {
55
+ assert.throws(() => {
56
+ MemberUtil.canReclaimHost();
57
+ }, 'canReclaimHostRole could not be processed, participant is undefined.');
58
+ });
59
+
60
+ it('returns true when canReclaimHostRole is true', () => {
61
+ const participant = {
62
+ canReclaimHostRole: true,
63
+ };
64
+
65
+ assert.isTrue(MemberUtil.canReclaimHost(participant));
66
+ });
67
+
68
+ it('returns false when canReclaimHostRole is false', () => {
69
+ const participant = {
70
+ canReclaimHostRole: false,
71
+ };
72
+
73
+ assert.isFalse(MemberUtil.canReclaimHost(participant));
74
+ });
75
+
76
+ it('returns false when canReclaimHostRole is falsy', () => {
77
+ const participant = {
78
+ canReclaimHostRole: undefined,
79
+ };
80
+
81
+ assert.isFalse(MemberUtil.canReclaimHost(participant));
82
+ });
83
+ });
84
+
53
85
  describe('MemberUtil.extractControlRoles', () => {
54
86
  it('happy path extract control roles', () => {
55
87
  const participant = {
@@ -17,6 +17,12 @@ import MembersUtil from '@webex/plugin-meetings/src/members/util';
17
17
  import * as MembersRequestImport from '@webex/plugin-meetings/src/members/request';
18
18
  import Trigger from '@webex/plugin-meetings/src/common/events/trigger-proxy';
19
19
  import {EVENT_TRIGGERS} from '@webex/plugin-meetings/src/constants';
20
+ import {
21
+ ReclaimHostEmptyWrongKeyError,
22
+ ReclaimHostIsHostAlreadyError,
23
+ ReclaimHostNotAllowedError,
24
+ ReclaimHostNotSupportedError,
25
+ } from '../../../../src/common/errors/reclaim-host-role-errors';
20
26
 
21
27
  const {assert} = chai;
22
28
 
@@ -337,7 +343,17 @@ describe('plugin-meetings', () => {
337
343
  });
338
344
 
339
345
  describe('#assignRoles', () => {
340
- const setup = (locusUrl) => {
346
+ const fakeRoles = [
347
+ {type: 'PRESENTER', hasRole: true},
348
+ {type: 'MODERATOR', hasRole: false},
349
+ {type: 'COHOST', hasRole: true},
350
+ ];
351
+
352
+ const resolvedValue = "it worked";
353
+
354
+ const genericMessage = 'Generic error from the API';
355
+
356
+ const setup = (locusUrl, errorCode) => {
341
357
  const members = createMembers({url: locusUrl});
342
358
 
343
359
  const spies = {
@@ -345,9 +361,14 @@ describe('plugin-meetings', () => {
345
361
  MembersUtil,
346
362
  'generateRoleAssignmentMemberOptions'
347
363
  ),
348
- assignRolesMember: sandbox.spy(members.membersRequest, 'assignRolesMember'),
349
364
  };
350
365
 
366
+ if (errorCode) {
367
+ spies.assignRolesMember = sandbox.stub(members.membersRequest, 'assignRolesMember').rejects({body: {errorCode}, message: genericMessage});
368
+ } else {
369
+ spies.assignRolesMember = sandbox.stub(members.membersRequest, 'assignRolesMember').resolves(resolvedValue);
370
+ }
371
+
351
372
  return {members, spies};
352
373
  };
353
374
 
@@ -357,6 +378,21 @@ describe('plugin-meetings', () => {
357
378
  assert.notCalled(spies.assignRolesMember);
358
379
  };
359
380
 
381
+ const checkError = async (error, expectedMemberId, expectedRoles, expectedLocusUrl, resultPromise, expectedMessage, spies) => {
382
+ await assert.isRejected(resultPromise, error, expectedMessage);
383
+ assert.calledOnceWithExactly(
384
+ spies.generateRoleAssignmentMemberOptions,
385
+ expectedMemberId,
386
+ expectedRoles,
387
+ expectedLocusUrl
388
+ );
389
+ assert.calledOnceWithExactly(spies.assignRolesMember, {
390
+ memberId: expectedMemberId,
391
+ roles: expectedRoles,
392
+ locusUrl: expectedLocusUrl,
393
+ });
394
+ };
395
+
360
396
  const checkValid = async (
361
397
  resultPromise,
362
398
  spies,
@@ -364,7 +400,7 @@ describe('plugin-meetings', () => {
364
400
  expectedRoles,
365
401
  expectedLocusUrl
366
402
  ) => {
367
- await assert.isFulfilled(resultPromise);
403
+ const resolvedValue = await assert.isFulfilled(resultPromise);
368
404
  assert.calledOnceWithExactly(
369
405
  spies.generateRoleAssignmentMemberOptions,
370
406
  expectedMemberId,
@@ -376,7 +412,7 @@ describe('plugin-meetings', () => {
376
412
  roles: expectedRoles,
377
413
  locusUrl: expectedLocusUrl,
378
414
  });
379
- assert.strictEqual(resultPromise, spies.assignRolesMember.getCall(0).returnValue);
415
+ assert.strictEqual(resolvedValue, resolvedValue);
380
416
  };
381
417
 
382
418
  it('should not make a request if there is no member id', async () => {
@@ -387,7 +423,7 @@ describe('plugin-meetings', () => {
387
423
  await checkInvalid(
388
424
  resultPromise,
389
425
  'The member id must be defined to assign the roles to a member.',
390
- spies
426
+ spies,
391
427
  );
392
428
  });
393
429
 
@@ -399,7 +435,92 @@ describe('plugin-meetings', () => {
399
435
  await checkInvalid(
400
436
  resultPromise,
401
437
  'The associated locus url for this meetings members object must be defined.',
402
- spies
438
+ spies,
439
+ );
440
+ });
441
+
442
+ it('should not make a request if locus throws ReclaimHostNotSupportedError', async () => {
443
+ const memberId = uuid.v4();
444
+ const {members, spies} = setup(url1, 2400127);
445
+
446
+ const resultPromise = members.assignRoles(memberId, fakeRoles);
447
+
448
+ await checkError(
449
+ ReclaimHostNotSupportedError,
450
+ memberId,
451
+ fakeRoles,
452
+ url1,
453
+ resultPromise,
454
+ 'Non converged meetings, PSTN or SIP users in converged meetings are not supported currently.',
455
+ spies,
456
+ );
457
+ });
458
+
459
+ it('should not make a request if locus throws ReclaimHostNotAllowedError', async () => {
460
+ const memberId = uuid.v4();
461
+ const {members, spies} = setup(url1, 2403135);
462
+
463
+ const resultPromise = members.assignRoles(memberId, fakeRoles);
464
+
465
+ await checkError(
466
+ ReclaimHostNotAllowedError,
467
+ memberId,
468
+ fakeRoles,
469
+ url1,
470
+ resultPromise,
471
+ 'Reclaim Host Role Not Allowed For Other Participants. Participants cannot claim host role in PMR meeting, space instant meeting or escalated instant meeting. However, the original host still can reclaim host role when it manually makes another participant to be the host.',
472
+ spies,
473
+ );
474
+ });
475
+
476
+ it('should not make a request if locus throws ReclaimHostEmptyWrongKeyError', async () => {
477
+ const memberId = uuid.v4();
478
+ const {members, spies} = setup(url1, 2403136);
479
+
480
+ const resultPromise = members.assignRoles(memberId, fakeRoles);
481
+
482
+ await checkError(
483
+ ReclaimHostEmptyWrongKeyError,
484
+ memberId,
485
+ fakeRoles,
486
+ url1,
487
+ resultPromise,
488
+ 'Host Key Not Specified Or Matched. The original host can reclaim the host role without entering the host key. However, any other person who claims the host role must enter the host key to get it.',
489
+ spies,
490
+ );
491
+ });
492
+
493
+ it('should not make a request if locus throws ReclaimHostIsHostAlreadyError', async () => {
494
+ const memberId = uuid.v4();
495
+ const {members, spies} = setup(url1, 2409150);
496
+
497
+ const resultPromise = members.assignRoles(memberId, fakeRoles);
498
+
499
+ await checkError(
500
+ ReclaimHostIsHostAlreadyError,
501
+ memberId,
502
+ fakeRoles,
503
+ url1,
504
+ resultPromise,
505
+ 'Participant Having Host Role Already. Participant who sends request to reclaim host role has already a host role.',
506
+ spies,
507
+ );
508
+ });
509
+
510
+ it('should not make a request if locus throws a different error', async () => {
511
+ const memberId = uuid.v4();
512
+ const {members, spies} = setup(url1, 1234);
513
+
514
+ const resultPromise = members.assignRoles(memberId, fakeRoles);
515
+
516
+ await checkError(
517
+ {body: {errorCode: 1234}, message: genericMessage},
518
+ memberId,
519
+ fakeRoles,
520
+ url1,
521
+ resultPromise,
522
+ genericMessage,
523
+ spies,
403
524
  );
404
525
  });
405
526
 
@@ -407,22 +528,14 @@ describe('plugin-meetings', () => {
407
528
  const memberId = uuid.v4();
408
529
  const {members, spies} = setup(url1);
409
530
 
410
- const resultPromise = members.assignRoles(memberId, [
411
- {type: 'PRESENTER', hasRole: true},
412
- {type: 'MODERATOR', hasRole: false},
413
- {type: 'COHOST', hasRole: true},
414
- ]);
531
+ const resultPromise = members.assignRoles(memberId, fakeRoles);
415
532
 
416
533
  await checkValid(
417
534
  resultPromise,
418
535
  spies,
419
536
  memberId,
420
- [
421
- {type: 'PRESENTER', hasRole: true},
422
- {type: 'MODERATOR', hasRole: false},
423
- {type: 'COHOST', hasRole: true},
424
- ],
425
- url1
537
+ fakeRoles,
538
+ url1,
426
539
  );
427
540
  });
428
541
  });
@@ -59,6 +59,32 @@ describe('plugin-meetings', () => {
59
59
  },
60
60
  });
61
61
  });
62
+
63
+ it('returns the correct request params with a hostKey', () => {
64
+ const format = {
65
+ locusUrl: 'locusUrl',
66
+ memberId: 'test',
67
+ roles: [
68
+ {type: 'PRESENTER', hasRole: true, hostKey: '123456'},
69
+ {type: 'MODERATOR', hasRole: false, hostKey: '123456'},
70
+ {type: 'COHOST', hasRole: true, hostKey: '123456'},
71
+ ],
72
+ };
73
+
74
+ assert.deepEqual(MembersUtil.getRoleAssignmentMemberRequestParams(format), {
75
+ method: 'PATCH',
76
+ uri: `locusUrl/${PARTICIPANT}/test/${CONTROLS}`,
77
+ body: {
78
+ role: {
79
+ roles: [
80
+ {type: 'PRESENTER', hasRole: true, hostKey: '123456'},
81
+ {type: 'MODERATOR', hasRole: false, hostKey: '123456'},
82
+ {type: 'COHOST', hasRole: true, hostKey: '123456'},
83
+ ],
84
+ },
85
+ },
86
+ });
87
+ });
62
88
  });
63
89
 
64
90
  describe('#generateRaiseHandMemberOptions', () => {
@@ -5,7 +5,6 @@ import 'jsdom-global/register';
5
5
  import sinon from 'sinon';
6
6
  import Metrics from '@webex/internal-plugin-metrics';
7
7
  import MockWebex from '@webex/test-helper-mock-webex';
8
- import {browserOnly} from '@webex/test-helper-mocha';
9
8
  import {assert} from '@webex/test-helper-chai';
10
9
 
11
10
  import metrics from '@webex/plugin-meetings/src/metrics';
@@ -14,7 +13,7 @@ import metrics from '@webex/plugin-meetings/src/metrics';
14
13
  * Meeting can only run in a browser, so we can only send metrics for
15
14
  * browser usage.
16
15
  */
17
- browserOnly(describe)('Meeting metrics', () => {
16
+ describe('Meeting metrics', () => {
18
17
  let webex, mockSubmitMetric, sandbox;
19
18
 
20
19
  beforeEach(() => {
@@ -951,6 +951,7 @@ describe('MediaRequestManager', () => {
951
951
  maxMbps: 3000,
952
952
  },
953
953
  ]);
954
+ clock.uninstall()
954
955
  });
955
956
 
956
957
  describe('maxPayloadBitsPerSecond', () => {
@@ -0,0 +1,279 @@
1
+ import {assert} from '@webex/test-helper-chai';
2
+ import MockWebex from '@webex/test-helper-mock-webex';
3
+ import sinon from 'sinon';
4
+ import testUtils from '../../../utils/testUtils';
5
+
6
+ // packages/@webex/plugin-meetings/test/unit/spec/reachability/clusterReachability.ts
7
+ import { ClusterReachability } from '@webex/plugin-meetings/src/reachability/clusterReachability'; // replace with actual path
8
+
9
+ describe('ClusterReachability', () => {
10
+ let previousRTCPeerConnection;
11
+ let clusterReachability;
12
+ let fakePeerConnection;
13
+
14
+ const FAKE_OFFER = {type: 'offer', sdp: 'fake sdp'};
15
+
16
+ beforeEach(() => {
17
+ fakePeerConnection = {
18
+ createOffer: sinon.stub().resolves(FAKE_OFFER),
19
+ setLocalDescription: sinon.stub().resolves(),
20
+ close: sinon.stub(),
21
+ iceGatheringState: 'new',
22
+ };
23
+
24
+ previousRTCPeerConnection = global.RTCPeerConnection;
25
+ global.RTCPeerConnection = sinon.stub().returns(fakePeerConnection);
26
+
27
+ clusterReachability = new ClusterReachability('testName', {
28
+ isVideoMesh: false,
29
+ udp: ['stun:udp1', 'stun:udp2'],
30
+ tcp: ['stun:tcp1.webex.com', 'stun:tcp2.webex.com:5004'],
31
+ xtls: ['xtls1', 'xtls2'],
32
+ });
33
+
34
+ });
35
+
36
+ afterEach(() => {
37
+ global.RTCPeerConnection = previousRTCPeerConnection;
38
+ });
39
+
40
+ it('should create an instance correctly', () => {
41
+ assert.instanceOf(clusterReachability, ClusterReachability);
42
+ assert.equal(clusterReachability.name, 'testName');
43
+ assert.equal(clusterReachability.isVideoMesh, false);
44
+ assert.equal(clusterReachability.numUdpUrls, 2);
45
+ assert.equal(clusterReachability.numTcpUrls, 2);
46
+ });
47
+
48
+ it('should create a peer connection with the right config', () => {
49
+ assert.calledOnceWithExactly(global.RTCPeerConnection, {
50
+ iceServers: [
51
+ {username: '', credential: '', urls: ['stun:udp1']},
52
+ {username: '', credential: '', urls: ['stun:udp2']},
53
+ {username: 'webexturnreachuser', credential: 'webexturnreachpwd', urls: ['turn:tcp1.webex.com?transport=tcp']},
54
+ {username: 'webexturnreachuser', credential: 'webexturnreachpwd', urls: ['turn:tcp2.webex.com:5004?transport=tcp']}
55
+ ],
56
+ iceCandidatePoolSize: 0,
57
+ iceTransportPolicy: 'all',
58
+ });
59
+ });
60
+
61
+ it('should create a peer connection with the right config even if lists of urls are empty', () => {
62
+ (global.RTCPeerConnection as any).resetHistory();
63
+
64
+ clusterReachability = new ClusterReachability('testName', {
65
+ isVideoMesh: false,
66
+ udp: [],
67
+ tcp: [],
68
+ xtls: [],
69
+ });
70
+
71
+ assert.calledOnceWithExactly(global.RTCPeerConnection, {
72
+ iceServers: [],
73
+ iceCandidatePoolSize: 0,
74
+ iceTransportPolicy: 'all',
75
+ });
76
+ });
77
+
78
+ it('returns correct results before start() is called', () => {
79
+ assert.deepEqual(clusterReachability.getResult(), {
80
+ udp: {result: 'untested'},
81
+ tcp: {result: 'untested'},
82
+ xtls: {result: 'untested'}
83
+ });
84
+ });
85
+
86
+ describe('#start', () => {
87
+ let clock;
88
+
89
+ beforeEach(() => {
90
+ clock = sinon.useFakeTimers();
91
+ });
92
+
93
+ afterEach(() => {
94
+ clock.restore();
95
+ })
96
+
97
+ it('should initiate the ICE gathering process', async () => {
98
+ const promise = clusterReachability.start();
99
+
100
+ await testUtils.flushPromises();
101
+
102
+ // check that the right listeners are setup
103
+ assert.isFunction(fakePeerConnection.onicecandidate);
104
+ assert.isFunction(fakePeerConnection.onicegatheringstatechange);
105
+
106
+ // check that the right webrtc APIs are called
107
+ assert.calledOnceWithExactly(fakePeerConnection.createOffer, {offerToReceiveAudio: true});
108
+ assert.calledOnce(fakePeerConnection.setLocalDescription);
109
+
110
+ await clock.tickAsync(3000);// move the clock so that reachability times out
111
+ await promise;
112
+ });
113
+
114
+ it('resolves and has correct result as soon as it finds that both udp and tcp is reachable', async () => {
115
+ const promise = clusterReachability.start();
116
+
117
+ await clock.tickAsync(100);
118
+ fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp'}});
119
+
120
+ await clock.tickAsync(100);
121
+ fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp'}});
122
+
123
+ await promise;
124
+
125
+ assert.deepEqual(clusterReachability.getResult(), {
126
+ udp: {result: 'reachable', latencyInMilliseconds: 100, clientMediaIPs: ['somePublicIp']},
127
+ tcp: {result: 'reachable', latencyInMilliseconds: 200},
128
+ xtls: {result: 'untested'}
129
+ });
130
+ });
131
+
132
+ it('times out correctly', async () => {
133
+ const promise = clusterReachability.start();
134
+
135
+ // progress time without any candidates
136
+ await clock.tickAsync(3000);
137
+ await promise;
138
+
139
+ assert.deepEqual(clusterReachability.getResult(), {
140
+ udp: {result: 'unreachable'},
141
+ tcp: {result: 'unreachable'},
142
+ xtls: {result: 'untested'}
143
+ });
144
+ });
145
+
146
+ it('times out correctly for video mesh nodes', async () => {
147
+ clusterReachability = new ClusterReachability('testName', {
148
+ isVideoMesh: true,
149
+ udp: ['stun:udp1', 'stun:udp2'],
150
+ tcp: ['stun:tcp1.webex.com', 'stun:tcp2.webex.com:5004'],
151
+ xtls: ['xtls1', 'xtls2'],
152
+ });
153
+
154
+ const promise = clusterReachability.start();
155
+
156
+ // video mesh nodes have shorter timeout of just 1s
157
+ await clock.tickAsync(1000);
158
+ await promise;
159
+
160
+ assert.deepEqual(clusterReachability.getResult(), {
161
+ udp: {result: 'unreachable'},
162
+ tcp: {result: 'unreachable'},
163
+ xtls: {result: 'untested'}
164
+ });
165
+ });
166
+
167
+ it('resolves when ICE gathering is completed', async () => {
168
+ const promise = clusterReachability.start();
169
+
170
+ await testUtils.flushPromises();
171
+
172
+ fakePeerConnection.iceConnectionState = 'complete';
173
+ fakePeerConnection.onicegatheringstatechange();
174
+ await promise;
175
+
176
+ assert.deepEqual(clusterReachability.getResult(), {
177
+ udp: {result: 'unreachable'},
178
+ tcp: {result: 'unreachable'},
179
+ xtls: {result: 'untested'}
180
+ });
181
+ });
182
+
183
+ it('resolves with the right result when ICE gathering is completed', async () => {
184
+ const promise = clusterReachability.start();
185
+
186
+ // send 1 candidate
187
+ await clock.tickAsync(30);
188
+ fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1'}});
189
+
190
+ fakePeerConnection.iceConnectionState = 'complete';
191
+ fakePeerConnection.onicegatheringstatechange();
192
+ await promise;
193
+
194
+ assert.deepEqual(clusterReachability.getResult(), {
195
+ udp: {result: 'reachable', latencyInMilliseconds: 30, clientMediaIPs: ['somePublicIp1']},
196
+ tcp: {result: 'unreachable'},
197
+ xtls: {result: 'untested'}
198
+ });
199
+ });
200
+
201
+ it('should store latency only for the first srflx candidate, but IPs from all of them', async () => {
202
+ const promise = clusterReachability.start();
203
+
204
+ await clock.tickAsync(10);
205
+ fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1'}});
206
+
207
+ // generate more candidates
208
+ await clock.tickAsync(10);
209
+ fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp2'}});
210
+
211
+ await clock.tickAsync(10);
212
+ fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp3'}});
213
+
214
+ await clock.tickAsync(3000);// move the clock so that reachability times out
215
+
216
+ await promise;
217
+
218
+ // latency should be from only the first candidates, but the clientMediaIps should be from all UDP candidates (not TCP)
219
+ assert.deepEqual(clusterReachability.getResult(), {
220
+ udp: {result: 'reachable', latencyInMilliseconds: 10, clientMediaIPs: ['somePublicIp1', 'somePublicIp2', 'somePublicIp3']},
221
+ tcp: {result: 'unreachable'},
222
+ xtls: {result: 'untested'}
223
+ });
224
+ });
225
+
226
+ it('should store latency only for the first relay candidate', async () => {
227
+ const promise = clusterReachability.start();
228
+
229
+ await clock.tickAsync(10);
230
+ fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp1'}});
231
+
232
+ // generate more candidates
233
+ await clock.tickAsync(10);
234
+ fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp2'}});
235
+
236
+ await clock.tickAsync(10);
237
+ fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp3'}});
238
+
239
+ await clock.tickAsync(3000);// move the clock so that reachability times out
240
+
241
+ await promise;
242
+
243
+ // latency should be from only the first candidates, but the clientMediaIps should be from only from UDP candidates
244
+ assert.deepEqual(clusterReachability.getResult(), {
245
+ udp: {result: 'unreachable'},
246
+ tcp: {result: 'reachable', latencyInMilliseconds: 10},
247
+ xtls: {result: 'untested'}
248
+ });
249
+ });
250
+
251
+ it('ignores duplicate clientMediaIps', async () => {
252
+ const promise = clusterReachability.start();
253
+
254
+ // generate candidates with duplicate addresses
255
+ await clock.tickAsync(10);
256
+ fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1'}});
257
+
258
+ await clock.tickAsync(10);
259
+ fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1'}});
260
+
261
+ await clock.tickAsync(10);
262
+ fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp2'}});
263
+
264
+ await clock.tickAsync(10);
265
+ fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp2'}});
266
+
267
+ // send also a relay candidate so that the reachability check finishes
268
+ fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp'}});
269
+
270
+ await promise;
271
+
272
+ assert.deepEqual(clusterReachability.getResult(), {
273
+ udp: {result: 'reachable', latencyInMilliseconds: 10, clientMediaIPs: ['somePublicIp1', 'somePublicIp2']},
274
+ tcp: {result: 'reachable', latencyInMilliseconds: 40},
275
+ xtls: {result: 'untested'}
276
+ });
277
+ });
278
+ });
279
+ });