@webex/plugin-meetings 3.0.0-beta.39 → 3.0.0-beta.391

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 (393) hide show
  1. package/README.md +58 -8
  2. package/dist/annotation/annotation.types.js +7 -0
  3. package/dist/annotation/annotation.types.js.map +1 -0
  4. package/dist/annotation/constants.js +49 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +342 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +94 -15
  9. package/dist/breakouts/breakout.js.map +1 -1
  10. package/dist/breakouts/events.js +45 -0
  11. package/dist/breakouts/events.js.map +1 -0
  12. package/dist/breakouts/index.js +671 -81
  13. package/dist/breakouts/index.js.map +1 -1
  14. package/dist/breakouts/utils.js +45 -1
  15. package/dist/breakouts/utils.js.map +1 -1
  16. package/dist/common/errors/no-meeting-info.js +51 -0
  17. package/dist/common/errors/no-meeting-info.js.map +1 -0
  18. package/dist/common/errors/reclaim-host-role-errors.js +158 -0
  19. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  20. package/dist/common/errors/webex-errors.js +48 -7
  21. package/dist/common/errors/webex-errors.js.map +1 -1
  22. package/dist/common/logs/logger-proxy.js +1 -1
  23. package/dist/common/logs/logger-proxy.js.map +1 -1
  24. package/dist/common/logs/request.js +5 -1
  25. package/dist/common/logs/request.js.map +1 -1
  26. package/dist/common/queue.js +24 -9
  27. package/dist/common/queue.js.map +1 -1
  28. package/dist/config.js +5 -10
  29. package/dist/config.js.map +1 -1
  30. package/dist/constants.js +242 -33
  31. package/dist/constants.js.map +1 -1
  32. package/dist/controls-options-manager/enums.js +14 -2
  33. package/dist/controls-options-manager/enums.js.map +1 -1
  34. package/dist/controls-options-manager/index.js +109 -15
  35. package/dist/controls-options-manager/index.js.map +1 -1
  36. package/dist/controls-options-manager/types.js +7 -0
  37. package/dist/controls-options-manager/types.js.map +1 -0
  38. package/dist/controls-options-manager/util.js +309 -18
  39. package/dist/controls-options-manager/util.js.map +1 -1
  40. package/dist/index.js +110 -2
  41. package/dist/index.js.map +1 -1
  42. package/dist/interceptors/index.js +15 -0
  43. package/dist/interceptors/index.js.map +1 -0
  44. package/dist/interceptors/locusRetry.js +93 -0
  45. package/dist/interceptors/locusRetry.js.map +1 -0
  46. package/dist/interpretation/collection.js +23 -0
  47. package/dist/interpretation/collection.js.map +1 -0
  48. package/dist/interpretation/index.js +380 -0
  49. package/dist/interpretation/index.js.map +1 -0
  50. package/dist/interpretation/siLanguage.js +25 -0
  51. package/dist/interpretation/siLanguage.js.map +1 -0
  52. package/dist/locus-info/controlsUtils.js +91 -2
  53. package/dist/locus-info/controlsUtils.js.map +1 -1
  54. package/dist/locus-info/index.js +386 -62
  55. package/dist/locus-info/index.js.map +1 -1
  56. package/dist/locus-info/infoUtils.js +7 -1
  57. package/dist/locus-info/infoUtils.js.map +1 -1
  58. package/dist/locus-info/mediaSharesUtils.js +71 -1
  59. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  60. package/dist/locus-info/parser.js +249 -72
  61. package/dist/locus-info/parser.js.map +1 -1
  62. package/dist/locus-info/selfUtils.js +89 -14
  63. package/dist/locus-info/selfUtils.js.map +1 -1
  64. package/dist/media/index.js +65 -102
  65. package/dist/media/index.js.map +1 -1
  66. package/dist/media/properties.js +73 -124
  67. package/dist/media/properties.js.map +1 -1
  68. package/dist/mediaQualityMetrics/config.js +135 -330
  69. package/dist/mediaQualityMetrics/config.js.map +1 -1
  70. package/dist/meeting/in-meeting-actions.js +86 -2
  71. package/dist/meeting/in-meeting-actions.js.map +1 -1
  72. package/dist/meeting/index.js +4075 -2827
  73. package/dist/meeting/index.js.map +1 -1
  74. package/dist/meeting/locusMediaRequest.js +292 -0
  75. package/dist/meeting/locusMediaRequest.js.map +1 -0
  76. package/dist/meeting/muteState.js +224 -136
  77. package/dist/meeting/muteState.js.map +1 -1
  78. package/dist/meeting/request.js +177 -152
  79. package/dist/meeting/request.js.map +1 -1
  80. package/dist/meeting/util.js +672 -417
  81. package/dist/meeting/util.js.map +1 -1
  82. package/dist/meeting-info/index.js +73 -7
  83. package/dist/meeting-info/index.js.map +1 -1
  84. package/dist/meeting-info/meeting-info-v2.js +192 -51
  85. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  86. package/dist/meeting-info/util.js +1 -1
  87. package/dist/meeting-info/util.js.map +1 -1
  88. package/dist/meeting-info/utilv2.js +36 -36
  89. package/dist/meeting-info/utilv2.js.map +1 -1
  90. package/dist/meetings/collection.js +39 -0
  91. package/dist/meetings/collection.js.map +1 -1
  92. package/dist/meetings/index.js +484 -119
  93. package/dist/meetings/index.js.map +1 -1
  94. package/dist/meetings/meetings.types.js +7 -0
  95. package/dist/meetings/meetings.types.js.map +1 -0
  96. package/dist/meetings/request.js +2 -0
  97. package/dist/meetings/request.js.map +1 -1
  98. package/dist/meetings/util.js +73 -7
  99. package/dist/meetings/util.js.map +1 -1
  100. package/dist/member/index.js +58 -0
  101. package/dist/member/index.js.map +1 -1
  102. package/dist/member/types.js +25 -0
  103. package/dist/member/types.js.map +1 -0
  104. package/dist/member/util.js +132 -25
  105. package/dist/member/util.js.map +1 -1
  106. package/dist/members/collection.js +10 -0
  107. package/dist/members/collection.js.map +1 -1
  108. package/dist/members/index.js +102 -6
  109. package/dist/members/index.js.map +1 -1
  110. package/dist/members/request.js +106 -38
  111. package/dist/members/request.js.map +1 -1
  112. package/dist/members/types.js +15 -0
  113. package/dist/members/types.js.map +1 -0
  114. package/dist/members/util.js +326 -232
  115. package/dist/members/util.js.map +1 -1
  116. package/dist/metrics/constants.js +18 -1
  117. package/dist/metrics/constants.js.map +1 -1
  118. package/dist/metrics/index.js +1 -446
  119. package/dist/metrics/index.js.map +1 -1
  120. package/dist/multistream/mediaRequestManager.js +223 -32
  121. package/dist/multistream/mediaRequestManager.js.map +1 -1
  122. package/dist/multistream/receiveSlot.js +10 -0
  123. package/dist/multistream/receiveSlot.js.map +1 -1
  124. package/dist/multistream/receiveSlotManager.js +39 -36
  125. package/dist/multistream/receiveSlotManager.js.map +1 -1
  126. package/dist/multistream/remoteMedia.js +3 -1
  127. package/dist/multistream/remoteMedia.js.map +1 -1
  128. package/dist/multistream/remoteMediaGroup.js +76 -5
  129. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  130. package/dist/multistream/remoteMediaManager.js +366 -104
  131. package/dist/multistream/remoteMediaManager.js.map +1 -1
  132. package/dist/multistream/sendSlotManager.js +255 -0
  133. package/dist/multistream/sendSlotManager.js.map +1 -0
  134. package/dist/reachability/clusterReachability.js +356 -0
  135. package/dist/reachability/clusterReachability.js.map +1 -0
  136. package/dist/reachability/index.js +263 -390
  137. package/dist/reachability/index.js.map +1 -1
  138. package/dist/reachability/request.js +6 -4
  139. package/dist/reachability/request.js.map +1 -1
  140. package/dist/reachability/util.js +29 -0
  141. package/dist/reachability/util.js.map +1 -0
  142. package/dist/reconnection-manager/index.js +266 -202
  143. package/dist/reconnection-manager/index.js.map +1 -1
  144. package/dist/recording-controller/index.js +21 -2
  145. package/dist/recording-controller/index.js.map +1 -1
  146. package/dist/recording-controller/util.js +9 -8
  147. package/dist/recording-controller/util.js.map +1 -1
  148. package/dist/roap/index.js +51 -28
  149. package/dist/roap/index.js.map +1 -1
  150. package/dist/roap/request.js +48 -64
  151. package/dist/roap/request.js.map +1 -1
  152. package/dist/roap/turnDiscovery.js +220 -70
  153. package/dist/roap/turnDiscovery.js.map +1 -1
  154. package/dist/rtcMetrics/constants.js +12 -0
  155. package/dist/rtcMetrics/constants.js.map +1 -0
  156. package/dist/rtcMetrics/index.js +179 -0
  157. package/dist/rtcMetrics/index.js.map +1 -0
  158. package/dist/statsAnalyzer/index.js +357 -295
  159. package/dist/statsAnalyzer/index.js.map +1 -1
  160. package/dist/statsAnalyzer/mqaUtil.js +296 -156
  161. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  162. package/dist/types/annotation/annotation.types.d.ts +42 -0
  163. package/dist/types/annotation/constants.d.ts +31 -0
  164. package/dist/types/annotation/index.d.ts +117 -0
  165. package/dist/types/breakouts/events.d.ts +8 -0
  166. package/dist/types/breakouts/utils.d.ts +14 -0
  167. package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
  168. package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
  169. package/dist/types/common/errors/webex-errors.d.ts +25 -1
  170. package/dist/types/common/logs/request.d.ts +2 -0
  171. package/dist/types/common/queue.d.ts +9 -7
  172. package/dist/types/config.d.ts +2 -7
  173. package/dist/types/constants.d.ts +203 -31
  174. package/dist/types/controls-options-manager/enums.d.ts +11 -1
  175. package/dist/types/controls-options-manager/index.d.ts +17 -1
  176. package/dist/types/controls-options-manager/types.d.ts +43 -0
  177. package/dist/types/controls-options-manager/util.d.ts +1 -7
  178. package/dist/types/index.d.ts +6 -5
  179. package/dist/types/interceptors/index.d.ts +2 -0
  180. package/dist/types/interceptors/locusRetry.d.ts +27 -0
  181. package/dist/types/interpretation/collection.d.ts +5 -0
  182. package/dist/types/interpretation/index.d.ts +5 -0
  183. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  184. package/dist/types/locus-info/index.d.ts +57 -4
  185. package/dist/types/locus-info/parser.d.ts +66 -6
  186. package/dist/types/media/index.d.ts +2 -0
  187. package/dist/types/media/properties.d.ts +34 -49
  188. package/dist/types/mediaQualityMetrics/config.d.ts +99 -223
  189. package/dist/types/meeting/in-meeting-actions.d.ts +86 -2
  190. package/dist/types/meeting/index.d.ts +567 -496
  191. package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
  192. package/dist/types/meeting/muteState.d.ts +93 -25
  193. package/dist/types/meeting/request.d.ts +64 -43
  194. package/dist/types/meeting/util.d.ts +117 -1
  195. package/dist/types/meeting-info/index.d.ts +13 -1
  196. package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
  197. package/dist/types/meetings/collection.d.ts +17 -0
  198. package/dist/types/meetings/index.d.ts +113 -21
  199. package/dist/types/meetings/meetings.types.d.ts +4 -0
  200. package/dist/types/member/index.d.ts +14 -0
  201. package/dist/types/member/types.d.ts +32 -0
  202. package/dist/types/members/collection.d.ts +5 -0
  203. package/dist/types/members/index.d.ts +35 -2
  204. package/dist/types/members/request.d.ts +73 -9
  205. package/dist/types/members/types.d.ts +25 -0
  206. package/dist/types/members/util.d.ts +214 -1
  207. package/dist/types/metrics/constants.d.ts +17 -0
  208. package/dist/types/metrics/index.d.ts +4 -111
  209. package/dist/types/multistream/mediaRequestManager.d.ts +72 -3
  210. package/dist/types/multistream/receiveSlot.d.ts +7 -3
  211. package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
  212. package/dist/types/multistream/remoteMedia.d.ts +3 -31
  213. package/dist/types/multistream/remoteMediaGroup.d.ts +2 -9
  214. package/dist/types/multistream/remoteMediaManager.d.ts +62 -2
  215. package/dist/types/multistream/sendSlotManager.d.ts +70 -0
  216. package/dist/types/reachability/clusterReachability.d.ts +109 -0
  217. package/dist/types/reachability/index.d.ts +60 -95
  218. package/dist/types/reachability/request.d.ts +3 -1
  219. package/dist/types/reachability/util.d.ts +8 -0
  220. package/dist/types/reconnection-manager/index.d.ts +19 -0
  221. package/dist/types/recording-controller/index.d.ts +15 -1
  222. package/dist/types/recording-controller/util.d.ts +5 -4
  223. package/dist/types/roap/index.d.ts +2 -1
  224. package/dist/types/roap/request.d.ts +9 -8
  225. package/dist/types/roap/turnDiscovery.d.ts +39 -5
  226. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  227. package/dist/types/rtcMetrics/index.d.ts +61 -0
  228. package/dist/types/statsAnalyzer/index.d.ts +34 -12
  229. package/dist/types/statsAnalyzer/mqaUtil.d.ts +28 -4
  230. package/dist/types/webinar/collection.d.ts +16 -0
  231. package/dist/types/webinar/index.d.ts +5 -0
  232. package/dist/webinar/collection.js +44 -0
  233. package/dist/webinar/collection.js.map +1 -0
  234. package/dist/webinar/index.js +69 -0
  235. package/dist/webinar/index.js.map +1 -0
  236. package/package.json +22 -19
  237. package/src/annotation/annotation.types.ts +50 -0
  238. package/src/annotation/constants.ts +36 -0
  239. package/src/annotation/index.ts +328 -0
  240. package/src/breakouts/README.md +35 -11
  241. package/src/breakouts/breakout.ts +67 -9
  242. package/src/breakouts/events.ts +56 -0
  243. package/src/breakouts/index.ts +558 -59
  244. package/src/breakouts/utils.ts +42 -0
  245. package/src/common/errors/no-meeting-info.ts +24 -0
  246. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  247. package/src/common/errors/webex-errors.ts +44 -2
  248. package/src/common/logs/logger-proxy.ts +1 -1
  249. package/src/common/logs/request.ts +5 -1
  250. package/src/common/queue.ts +22 -8
  251. package/src/config.ts +4 -9
  252. package/src/constants.ts +229 -21
  253. package/src/controls-options-manager/enums.ts +12 -0
  254. package/src/controls-options-manager/index.ts +116 -21
  255. package/src/controls-options-manager/types.ts +59 -0
  256. package/src/controls-options-manager/util.ts +294 -14
  257. package/src/index.ts +44 -0
  258. package/src/interceptors/index.ts +3 -0
  259. package/src/interceptors/locusRetry.ts +67 -0
  260. package/src/interpretation/README.md +60 -0
  261. package/src/interpretation/collection.ts +19 -0
  262. package/src/interpretation/index.ts +349 -0
  263. package/src/interpretation/siLanguage.ts +18 -0
  264. package/src/locus-info/controlsUtils.ts +108 -0
  265. package/src/locus-info/index.ts +417 -59
  266. package/src/locus-info/infoUtils.ts +10 -2
  267. package/src/locus-info/mediaSharesUtils.ts +80 -0
  268. package/src/locus-info/parser.ts +258 -47
  269. package/src/locus-info/selfUtils.ts +81 -5
  270. package/src/media/index.ts +100 -108
  271. package/src/media/properties.ts +88 -117
  272. package/src/mediaQualityMetrics/config.ts +103 -238
  273. package/src/meeting/in-meeting-actions.ts +171 -3
  274. package/src/meeting/index.ts +3411 -2435
  275. package/src/meeting/locusMediaRequest.ts +313 -0
  276. package/src/meeting/muteState.ts +223 -136
  277. package/src/meeting/request.ts +155 -120
  278. package/src/meeting/util.ts +685 -395
  279. package/src/meeting-info/index.ts +81 -8
  280. package/src/meeting-info/meeting-info-v2.ts +170 -14
  281. package/src/meeting-info/util.ts +1 -1
  282. package/src/meeting-info/utilv2.ts +23 -23
  283. package/src/meetings/collection.ts +33 -0
  284. package/src/meetings/index.ts +507 -127
  285. package/src/meetings/meetings.types.ts +12 -0
  286. package/src/meetings/request.ts +2 -0
  287. package/src/meetings/util.ts +81 -12
  288. package/src/member/index.ts +58 -0
  289. package/src/member/types.ts +38 -0
  290. package/src/member/util.ts +141 -25
  291. package/src/members/collection.ts +8 -0
  292. package/src/members/index.ts +134 -8
  293. package/src/members/request.ts +97 -17
  294. package/src/members/types.ts +29 -0
  295. package/src/members/util.ts +333 -240
  296. package/src/metrics/constants.ts +17 -0
  297. package/src/metrics/index.ts +1 -469
  298. package/src/multistream/mediaRequestManager.ts +271 -56
  299. package/src/multistream/receiveSlot.ts +11 -4
  300. package/src/multistream/receiveSlotManager.ts +34 -24
  301. package/src/multistream/remoteMedia.ts +5 -3
  302. package/src/multistream/remoteMediaGroup.ts +78 -0
  303. package/src/multistream/remoteMediaManager.ts +248 -44
  304. package/src/multistream/sendSlotManager.ts +199 -0
  305. package/src/reachability/clusterReachability.ts +320 -0
  306. package/src/reachability/index.ts +229 -346
  307. package/src/reachability/request.ts +8 -4
  308. package/src/reachability/util.ts +24 -0
  309. package/src/reconnection-manager/index.ts +128 -97
  310. package/src/recording-controller/index.ts +20 -3
  311. package/src/recording-controller/util.ts +26 -9
  312. package/src/roap/index.ts +52 -23
  313. package/src/roap/request.ts +48 -67
  314. package/src/roap/turnDiscovery.ts +147 -49
  315. package/src/rtcMetrics/constants.ts +3 -0
  316. package/src/rtcMetrics/index.ts +166 -0
  317. package/src/statsAnalyzer/index.ts +457 -416
  318. package/src/statsAnalyzer/mqaUtil.ts +317 -170
  319. package/src/webinar/collection.ts +31 -0
  320. package/src/webinar/index.ts +62 -0
  321. package/test/integration/spec/converged-space-meetings.js +60 -3
  322. package/test/integration/spec/journey.js +320 -261
  323. package/test/integration/spec/space-meeting.js +76 -3
  324. package/test/unit/spec/annotation/index.ts +418 -0
  325. package/test/unit/spec/breakouts/breakout.ts +118 -28
  326. package/test/unit/spec/breakouts/events.ts +89 -0
  327. package/test/unit/spec/breakouts/index.ts +1349 -114
  328. package/test/unit/spec/breakouts/utils.js +52 -1
  329. package/test/unit/spec/common/queue.js +31 -2
  330. package/test/unit/spec/controls-options-manager/index.js +163 -0
  331. package/test/unit/spec/controls-options-manager/util.js +576 -60
  332. package/test/unit/spec/fixture/locus.js +1 -0
  333. package/test/unit/spec/interceptors/locusRetry.ts +131 -0
  334. package/test/unit/spec/interpretation/collection.ts +15 -0
  335. package/test/unit/spec/interpretation/index.ts +625 -0
  336. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  337. package/test/unit/spec/locus-info/controlsUtils.js +316 -43
  338. package/test/unit/spec/locus-info/index.js +1363 -37
  339. package/test/unit/spec/locus-info/infoUtils.js +37 -15
  340. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  341. package/test/unit/spec/locus-info/mediaSharesUtils.ts +41 -0
  342. package/test/unit/spec/locus-info/parser.js +116 -35
  343. package/test/unit/spec/locus-info/selfConstant.js +27 -4
  344. package/test/unit/spec/locus-info/selfUtils.js +208 -17
  345. package/test/unit/spec/media/index.ts +173 -81
  346. package/test/unit/spec/media/properties.ts +2 -2
  347. package/test/unit/spec/meeting/in-meeting-actions.ts +85 -3
  348. package/test/unit/spec/meeting/index.js +6821 -2172
  349. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  350. package/test/unit/spec/meeting/muteState.js +402 -212
  351. package/test/unit/spec/meeting/request.js +473 -54
  352. package/test/unit/spec/meeting/utils.js +773 -67
  353. package/test/unit/spec/meeting-info/index.js +300 -0
  354. package/test/unit/spec/meeting-info/meetinginfov2.js +526 -5
  355. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  356. package/test/unit/spec/meetings/collection.js +26 -0
  357. package/test/unit/spec/meetings/index.js +1415 -213
  358. package/test/unit/spec/meetings/utils.js +229 -2
  359. package/test/unit/spec/member/index.js +61 -6
  360. package/test/unit/spec/member/util.js +510 -34
  361. package/test/unit/spec/members/index.js +432 -1
  362. package/test/unit/spec/members/request.js +206 -27
  363. package/test/unit/spec/members/utils.js +210 -0
  364. package/test/unit/spec/metrics/index.js +1 -50
  365. package/test/unit/spec/multistream/mediaRequestManager.ts +781 -114
  366. package/test/unit/spec/multistream/receiveSlot.ts +9 -1
  367. package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
  368. package/test/unit/spec/multistream/remoteMedia.ts +2 -0
  369. package/test/unit/spec/multistream/remoteMediaGroup.ts +345 -0
  370. package/test/unit/spec/multistream/remoteMediaManager.ts +525 -0
  371. package/test/unit/spec/multistream/sendSlotManager.ts +274 -0
  372. package/test/unit/spec/reachability/clusterReachability.ts +279 -0
  373. package/test/unit/spec/reachability/index.ts +551 -14
  374. package/test/unit/spec/reachability/request.js +3 -1
  375. package/test/unit/spec/reachability/util.ts +40 -0
  376. package/test/unit/spec/reconnection-manager/index.js +171 -11
  377. package/test/unit/spec/recording-controller/index.js +294 -218
  378. package/test/unit/spec/recording-controller/util.js +223 -96
  379. package/test/unit/spec/roap/index.ts +180 -83
  380. package/test/unit/spec/roap/request.ts +100 -62
  381. package/test/unit/spec/roap/turnDiscovery.ts +388 -96
  382. package/test/unit/spec/rtcMetrics/index.ts +122 -0
  383. package/test/unit/spec/stats-analyzer/index.js +1252 -12
  384. package/test/unit/spec/webinar/collection.ts +13 -0
  385. package/test/unit/spec/webinar/index.ts +60 -0
  386. package/test/utils/integrationTestUtils.js +46 -0
  387. package/test/utils/testUtils.js +0 -57
  388. package/test/utils/webex-test-users.js +12 -4
  389. package/dist/metrics/config.js +0 -289
  390. package/dist/metrics/config.js.map +0 -1
  391. package/dist/types/metrics/config.d.ts +0 -169
  392. package/src/index.js +0 -18
  393. package/src/metrics/config.ts +0 -485
@@ -1,13 +1,23 @@
1
1
  import {assert} from '@webex/test-helper-chai';
2
2
  import MockWebex from '@webex/test-helper-mock-webex';
3
3
  import sinon from 'sinon';
4
- import Reachability from '@webex/plugin-meetings/src/reachability/';
4
+ import Reachability, {ReachabilityResults, ReachabilityResultsForBackend} from '@webex/plugin-meetings/src/reachability/';
5
+ import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
6
+ import * as ClusterReachabilityModule from '@webex/plugin-meetings/src/reachability/clusterReachability';
5
7
 
6
- describe('isAnyClusterReachable', () => {
8
+ import { IP_VERSION } from '@webex/plugin-meetings/src/constants';
9
+
10
+ describe('isAnyPublicClusterReachable', () => {
7
11
  let webex;
8
12
 
9
13
  beforeEach(() => {
10
14
  webex = new MockWebex();
15
+
16
+ sinon.stub(MeetingUtil, 'getIpVersion').returns(IP_VERSION.unknown);
17
+ });
18
+
19
+ afterEach(() => {
20
+ sinon.restore();
11
21
  });
12
22
 
13
23
  const checkIsClusterReachable = async (mockStorage: any, expectedValue: boolean) => {
@@ -20,25 +30,25 @@ describe('isAnyClusterReachable', () => {
20
30
  }
21
31
  const reachability = new Reachability(webex);
22
32
 
23
- const result = await reachability.isAnyClusterReachable();
33
+ const result = await reachability.isAnyPublicClusterReachable();
24
34
 
25
- assert.equal(result, expectedValue);
26
- };
35
+ assert.equal(result, expectedValue);
36
+ };
27
37
 
28
38
  it('returns true when udp is reachable', async () => {
29
- await checkIsClusterReachable({x: {udp: {reachable: 'true'}, tcp: {reachable: 'false'}}}, true);
39
+ await checkIsClusterReachable({x: {udp: {result: 'reachable'}, tcp: {result: 'unreachable'}}}, true);
30
40
  });
31
41
 
32
42
  it('returns true when tcp is reachable', async () => {
33
- await checkIsClusterReachable({x: {udp: {reachable: 'false'}, tcp: {reachable: 'true'}}}, true);
43
+ await checkIsClusterReachable({x: {udp: {result: 'unreachable'}, tcp: {result: 'reachable'}}}, true);
34
44
  });
35
45
 
36
46
  it('returns true when both tcp and udp are reachable', async () => {
37
- await checkIsClusterReachable({x: {udp: {reachable: 'true'}, tcp: {reachable: 'true'}}}, true);
47
+ await checkIsClusterReachable({x: {udp: {result: 'reachable'}, tcp: {result: 'reachable'}}}, true);
38
48
  });
39
49
 
40
50
  it('returns false when both tcp and udp are unreachable', async () => {
41
- await checkIsClusterReachable({x: {udp: {reachable: 'false'}, tcp: {reachable: 'false'}}}, false);
51
+ await checkIsClusterReachable({x: {udp: {result: 'unreachable'}, tcp: {result: 'unreachable'}}}, false);
42
52
  });
43
53
 
44
54
  it('returns false when reachability result is empty', async () => {
@@ -48,6 +58,63 @@ describe('isAnyClusterReachable', () => {
48
58
  it('returns false when reachability.result item is not there', async () => {
49
59
  await checkIsClusterReachable(undefined, false);
50
60
  });
61
+
62
+ describe('ignores video mesh reachability', () => {
63
+ it('returns false if there are no public cluster results, only video mesh', async () => {
64
+ await checkIsClusterReachable({
65
+ x: {
66
+ udp: {result: 'reachable'},
67
+ tcp: {result: 'reachable'},
68
+ isVideoMesh: true,
69
+ },
70
+ y: {
71
+ udp: {result: 'unreachable'},
72
+ tcp: {result: 'reachable'},
73
+ isVideoMesh: true,
74
+ }
75
+ }, false);
76
+ });
77
+
78
+ it('returns false if there public cluster reachability failed, only video mesh succeeded', async () => {
79
+ await checkIsClusterReachable({
80
+ x: {
81
+ udp: {result: 'unreachable'},
82
+ tcp: {result: 'reachable'},
83
+ isVideoMesh: true,
84
+ },
85
+ y: {
86
+ udp: {result: 'reachable'},
87
+ tcp: {result: 'unreachable'},
88
+ isVideoMesh: true,
89
+ },
90
+ publicOne: {
91
+ udp: {result: 'unreachable'},
92
+ tcp: {result: 'unreachable'},
93
+ isVideoMesh: false,
94
+ }
95
+ }, false);
96
+ });
97
+
98
+ it('returns true if there is at least 1 public cluster result, while video mesh is not reachable', async () => {
99
+ await checkIsClusterReachable({
100
+ x: {
101
+ udp: {result: 'reachable'},
102
+ tcp: {result: 'reachable'},
103
+ isVideoMesh: true,
104
+ },
105
+ y: {
106
+ udp: {result: 'unreachable'},
107
+ tcp: {result: 'reachable'},
108
+ isVideoMesh: true,
109
+ },
110
+ publicOne: {
111
+ udp: {result: 'unreachable'},
112
+ tcp: {result: 'reachable'},
113
+ isVideoMesh: false,
114
+ }
115
+ }, true);
116
+ });
117
+ })
51
118
  });
52
119
 
53
120
  describe('gatherReachability', () => {
@@ -61,6 +128,15 @@ describe('gatherReachability', () => {
61
128
  'reachability.result',
62
129
  JSON.stringify({old: 'results'})
63
130
  );
131
+ await webex.boundedStorage.put(
132
+ 'Reachability',
133
+ 'reachability.joinCookie',
134
+ JSON.stringify({old: 'joinCookie'})
135
+ );
136
+ });
137
+
138
+ afterEach(() => {
139
+ sinon.restore();
64
140
  });
65
141
 
66
142
  it('stores the reachability', async () => {
@@ -72,24 +148,485 @@ describe('gatherReachability', () => {
72
148
  udp: 'testUDP',
73
149
  },
74
150
  },
75
- }
151
+ };
76
152
  const getClustersResult = {
77
153
  clusters: {clusterId: 'cluster'},
78
- joinCookie: {id: 'id'}
154
+ joinCookie: {id: 'id'},
79
155
  };
80
156
 
81
157
  reachability.reachabilityRequest.getClusters = sinon.stub().returns(getClustersResult);
82
- (reachability as any).performReachabilityCheck = sinon.stub().returns(reachabilityResults)
158
+ (reachability as any).performReachabilityChecks = sinon.stub().returns(reachabilityResults);
83
159
 
84
160
  const result = await reachability.gatherReachability();
85
161
 
86
162
  assert.equal(result, reachabilityResults);
87
163
 
88
- const storedResultForReachabilityResult = await webex.boundedStorage.get('Reachability', 'reachability.result');
89
- const storedResultForJoinCookie = await webex.boundedStorage.get('Reachability', 'reachability.joinCookie');
164
+ const storedResultForReachabilityResult = await webex.boundedStorage.get(
165
+ 'Reachability',
166
+ 'reachability.result'
167
+ );
168
+ const storedResultForJoinCookie = await webex.boundedStorage.get(
169
+ 'Reachability',
170
+ 'reachability.joinCookie'
171
+ );
90
172
 
91
173
  assert.equal(JSON.stringify(result), storedResultForReachabilityResult);
92
174
  assert.equal(JSON.stringify(getClustersResult.joinCookie), storedResultForJoinCookie);
93
175
  });
94
176
 
177
+ it('keeps the stored reachability from previous call to gatherReachability if getClusters fails', async () => {
178
+ const reachability = new Reachability(webex);
179
+
180
+ const reachabilityResults = {
181
+ clusters: {
182
+ clusterId: {
183
+ udp: 'testUDP',
184
+ },
185
+ },
186
+ };
187
+ const getClustersResult = {
188
+ clusters: {clusterId: 'cluster'},
189
+ joinCookie: {id: 'id'},
190
+ };
191
+
192
+ reachability.reachabilityRequest.getClusters = sinon.stub().throws();
193
+
194
+ const result = await reachability.gatherReachability();
195
+
196
+ assert.empty(result);
197
+
198
+ const storedResultForReachabilityResult = await webex.boundedStorage.get(
199
+ 'Reachability',
200
+ 'reachability.result'
201
+ );
202
+ const storedResultForJoinCookie = await webex.boundedStorage.get(
203
+ 'Reachability',
204
+ 'reachability.joinCookie'
205
+ );
206
+
207
+ assert.equal(JSON.stringify({old: 'results'}), storedResultForReachabilityResult);
208
+ assert.equal(JSON.stringify({old: 'joinCookie'}), storedResultForJoinCookie);
209
+ });
210
+
211
+ it('keeps the stored reachability from previous call to gatherReachability if performReachabilityChecks fails', async () => {
212
+ const reachability = new Reachability(webex);
213
+
214
+ const reachabilityResults = {
215
+ clusters: {
216
+ clusterId: {
217
+ udp: 'testUDP',
218
+ },
219
+ },
220
+ };
221
+ const getClustersResult = {
222
+ clusters: {clusterId: 'cluster'},
223
+ joinCookie: {id: 'id'},
224
+ };
225
+
226
+ reachability.reachabilityRequest.getClusters = sinon.stub().returns(getClustersResult);
227
+ (reachability as any).performReachabilityChecks = sinon.stub().throws();
228
+
229
+ const result = await reachability.gatherReachability();
230
+
231
+ assert.empty(result);
232
+
233
+ const storedResultForReachabilityResult = await webex.boundedStorage.get(
234
+ 'Reachability',
235
+ 'reachability.result'
236
+ );
237
+ const storedResultForJoinCookie = await webex.boundedStorage.get(
238
+ 'Reachability',
239
+ 'reachability.joinCookie'
240
+ );
241
+
242
+ assert.equal(JSON.stringify({old: 'results'}), storedResultForReachabilityResult);
243
+ assert.equal(JSON.stringify({old: 'joinCookie'}), storedResultForJoinCookie);
244
+ });
245
+
246
+ it('starts ClusterReachability on each media cluster', async () => {
247
+ webex.config.meetings.experimental = {enableTcpReachability: true};
248
+
249
+ const getClustersResult = {
250
+ clusters: {
251
+ 'cluster 1': {
252
+ udp: ['udp1.1', 'udp1.2'],
253
+ tcp: ['tcp1.1', 'tcp1.2'],
254
+ xtls: ['xtls1.1', 'xtls1.2'],
255
+ isVideoMesh: false,
256
+ },
257
+ 'cluster 2': {
258
+ udp: ['udp2.1', 'udp2.2'],
259
+ tcp: ['tcp2.1', 'tcp2.2'],
260
+ xtls: ['xtls2.1', 'xtls2.2'],
261
+ isVideoMesh: true,
262
+ },
263
+ },
264
+ joinCookie: {id: 'id'},
265
+ };
266
+
267
+ const reachability = new Reachability(webex);
268
+
269
+ reachability.reachabilityRequest.getClusters = sinon.stub().returns(getClustersResult);
270
+
271
+ const startStub = sinon.stub().resolves({});
272
+ const clusterReachabilityCtorStub = sinon
273
+ .stub(ClusterReachabilityModule, 'ClusterReachability')
274
+ .callsFake(() => ({
275
+ start: startStub,
276
+ }));
277
+
278
+ await reachability.gatherReachability();
279
+
280
+ assert.calledTwice(clusterReachabilityCtorStub);
281
+ assert.calledWith(clusterReachabilityCtorStub, 'cluster 1', {
282
+ udp: ['udp1.1', 'udp1.2'],
283
+ tcp: ['tcp1.1', 'tcp1.2'],
284
+ xtls: ['xtls1.1', 'xtls1.2'],
285
+ isVideoMesh: false,
286
+ });
287
+ // cluster 2 is video mesh, so we should not do TCP reachability on it
288
+ assert.calledWith(clusterReachabilityCtorStub, 'cluster 2', {
289
+ udp: ['udp2.1', 'udp2.2'],
290
+ tcp: [],
291
+ xtls: ['xtls2.1', 'xtls2.2'],
292
+ isVideoMesh: true,
293
+ });
294
+
295
+ assert.calledTwice(startStub);
296
+ });
297
+
298
+ it('does not do TCP reachability if it is disabled in config', async () => {
299
+ webex.config.meetings.experimental = {enableTcpReachability: false};
300
+
301
+ const getClustersResult = {
302
+ clusters: {
303
+ 'cluster name': {
304
+ udp: ['testUDP1', 'testUDP2'],
305
+ tcp: ['testTCP1', 'testTCP2'],
306
+ xtls: ['testXTLS1', 'testXTLS2'],
307
+ isVideoMesh: false,
308
+ },
309
+ },
310
+ joinCookie: {id: 'id'},
311
+ };
312
+
313
+ const reachability = new Reachability(webex);
314
+
315
+ reachability.reachabilityRequest.getClusters = sinon.stub().returns(getClustersResult);
316
+
317
+ const clusterReachabilityCtorStub = sinon
318
+ .stub(ClusterReachabilityModule, 'ClusterReachability')
319
+ .callsFake(() => ({
320
+ start: sinon.stub().resolves({}),
321
+ }));
322
+
323
+ await reachability.gatherReachability();
324
+
325
+ assert.calledOnceWithExactly(clusterReachabilityCtorStub, 'cluster name', {
326
+ isVideoMesh: false,
327
+ udp: ['testUDP1', 'testUDP2'],
328
+ tcp: [], // empty list because TCP is disabled in config
329
+ xtls: ['testXTLS1', 'testXTLS2'],
330
+ });
331
+ });
95
332
  });
333
+
334
+ describe('getReachabilityResults', () => {
335
+ let webex;
336
+
337
+ beforeEach(() => {
338
+ webex = new MockWebex();
339
+ });
340
+
341
+ afterEach(() => {
342
+ sinon.restore();
343
+ });
344
+
345
+ const runCheck = async (mockStorage: any, expectedResult: ReachabilityResultsForBackend) => {
346
+ if (mockStorage) {
347
+ await webex.boundedStorage.put(
348
+ 'Reachability',
349
+ 'reachability.result',
350
+ JSON.stringify(mockStorage)
351
+ );
352
+ }
353
+ const reachability = new Reachability(webex);
354
+
355
+ const result = await reachability.getReachabilityResults();
356
+
357
+ assert.deepEqual(result, expectedResult);
358
+ };
359
+
360
+ it('returns undefined if reading from local storage fails', async () => {
361
+ sinon.stub(webex.boundedStorage, 'get').rejects(new Error('fake error'));
362
+
363
+ const reachability = new Reachability(webex);
364
+
365
+ const result = await reachability.getReachabilityResults();
366
+
367
+ assert.isUndefined(result);
368
+ });
369
+
370
+ it('returns results from local storage, converted to the backend data format', async () => {
371
+ await runCheck(
372
+ // mock storage:
373
+ {
374
+ cluster1: {
375
+ udp: {result: 'reachable', latencyInMilliseconds: 100},
376
+ tcp: {result: 'unreachable'},
377
+ xtls: {result: 'untested'},
378
+ },
379
+ cluster2: {
380
+ udp: {result: 'reachable', latencyInMilliseconds: 200},
381
+ tcp: {result: 'unreachable'},
382
+ xtls: {result: 'untested'},
383
+ isVideoMesh: true,
384
+ },
385
+ cluster3: {
386
+ udp: {result: 'unreachable'},
387
+ tcp: {result: 'reachable', latencyInMilliseconds: 100, clientMediaIPs: ['10.10.10.10']},
388
+ xtls: {result: 'untested'},
389
+ isVideoMesh: true,
390
+ someOtherField: 'any value',
391
+ },
392
+ cluster4: {
393
+ udp: {result: 'reachable', latencyInMilliseconds: 300},
394
+ tcp: {result: 'untested'},
395
+ xtls: {result: 'untested'},
396
+ someOtherField: 'any value',
397
+ },
398
+ },
399
+ // expected result (same as above, but with values converted and isVideoMesh and someOtherField stripped out):
400
+ {
401
+ cluster1: {
402
+ udp: {reachable: 'true', latencyInMilliseconds: '100'},
403
+ tcp: {reachable: 'false'},
404
+ xtls: {untested: 'true'},
405
+ },
406
+ cluster2: {
407
+ udp: {reachable: 'true', latencyInMilliseconds: '200'},
408
+ tcp: {reachable: 'false'},
409
+ xtls: {untested: 'true'},
410
+ },
411
+ cluster3: {
412
+ udp: {reachable: 'false'},
413
+ tcp: {reachable: 'true', latencyInMilliseconds: '100', clientMediaIPs: ['10.10.10.10']},
414
+ xtls: {untested: 'true'},
415
+ },
416
+ cluster4: {
417
+ udp: {reachable: 'true', latencyInMilliseconds: '300'},
418
+ tcp: {untested: 'true'},
419
+ xtls: {untested: 'true'},
420
+ },
421
+ }
422
+ );
423
+ });
424
+ });
425
+
426
+ describe('getReachabilityMetrics', () => {
427
+ let webex;
428
+
429
+ beforeEach(() => {
430
+ webex = new MockWebex();
431
+ });
432
+
433
+ afterEach(() => {
434
+ sinon.restore();
435
+ });
436
+
437
+ const runCheck = async (mockStorage: any, expectedResult: any) => {
438
+ if (mockStorage) {
439
+ await webex.boundedStorage.put(
440
+ 'Reachability',
441
+ 'reachability.result',
442
+ JSON.stringify(mockStorage)
443
+ );
444
+ }
445
+ const reachability = new Reachability(webex);
446
+ const result = await reachability.getReachabilityMetrics();
447
+
448
+ assert.deepEqual(result, expectedResult);
449
+ };
450
+
451
+ it('returns all zeros if reading from local storage fails', async () => {
452
+ sinon.stub(webex.boundedStorage, 'get').rejects(new Error('fake error'));
453
+
454
+ const reachability = new Reachability(webex);
455
+
456
+ const result = await reachability.getReachabilityMetrics();
457
+
458
+ assert.deepEqual(result, {
459
+ reachability_public_udp_success: 0,
460
+ reachability_public_udp_failed: 0,
461
+ reachability_public_tcp_success: 0,
462
+ reachability_public_tcp_failed: 0,
463
+ reachability_vmn_udp_success: 0,
464
+ reachability_vmn_udp_failed: 0,
465
+ reachability_vmn_tcp_success: 0,
466
+ reachability_vmn_tcp_failed: 0,
467
+ });
468
+ });
469
+
470
+ it('returns correct stats based on local storage results', async () => {
471
+ await runCheck(
472
+ // mock storage:
473
+ {
474
+ public1: {
475
+ udp: {result: 'reachable', latencyInMilliseconds: 100},
476
+ tcp: {result: 'untested'},
477
+ xtls: {result: 'untested'},
478
+ },
479
+ vmn1: {
480
+ udp: {result: 'reachable', latencyInMilliseconds: 200},
481
+ tcp: {result: 'unreachable'},
482
+ xtls: {result: 'untested'},
483
+ isVideoMesh: true,
484
+ },
485
+ vmn2: {
486
+ udp: {result: 'untested'},
487
+ tcp: {result: 'reachable', latencyInMilliseconds: 100, clientMediaIPs: ['10.10.10.10']},
488
+ xtls: {result: 'untested'},
489
+ isVideoMesh: true,
490
+ someOtherField: 'any value',
491
+ },
492
+ public2: {
493
+ udp: {result: 'unreachable'},
494
+ tcp: {result: 'unreachable'},
495
+ xtls: {result: 'untested'},
496
+ someOtherField: 'any value',
497
+ },
498
+ public3: {
499
+ udp: {result: 'reachable', latencyInMilliseconds: 400, clientMediaIPs: ['10.10.10.10']},
500
+ tcp: {result: 'reachable', latencyInMilliseconds: 100, clientMediaIPs: ['10.10.10.10']},
501
+ xtls: {result: 'untested'},
502
+ isVideoMesh: false,
503
+ someOtherField: 'any value',
504
+ },
505
+ public4: {
506
+ udp: {result: 'reachable', latencyInMilliseconds: 40, clientMediaIPs: ['10.10.10.11']},
507
+ tcp: {result: 'reachable', latencyInMilliseconds: 100, clientMediaIPs: ['10.10.10.11']},
508
+ xtls: {result: 'untested'},
509
+ isVideoMesh: false,
510
+ someOtherField: 'any value',
511
+ },
512
+ public5: {
513
+ udp: {result: 'unreachable'},
514
+ tcp: {result: 'untested'},
515
+ xtls: {result: 'untested'},
516
+ isVideoMesh: false,
517
+ someOtherField: 'any value',
518
+ },
519
+ },
520
+ // expected result:
521
+ {
522
+ reachability_public_udp_success: 3,
523
+ reachability_public_udp_failed: 2,
524
+ reachability_public_tcp_success: 2,
525
+ reachability_public_tcp_failed: 1,
526
+ reachability_vmn_udp_success: 1,
527
+ reachability_vmn_udp_failed: 0,
528
+ reachability_vmn_tcp_success: 1,
529
+ reachability_vmn_tcp_failed: 1,
530
+ }
531
+ );
532
+ });
533
+
534
+ it('returns correct stats when only public nodes were tested', async () => {
535
+ await runCheck(
536
+ // mock storage:
537
+ {
538
+ public1: {
539
+ udp: {result: 'reachable', latencyInMilliseconds: 400, clientMediaIPs: ['10.10.10.10']},
540
+ tcp: {result: 'reachable', latencyInMilliseconds: 100, clientMediaIPs: ['10.10.10.10']},
541
+ xtls: {result: 'untested'},
542
+ isVideoMesh: false,
543
+ },
544
+ public2: {
545
+ udp: {result: 'reachable', latencyInMilliseconds: 100},
546
+ tcp: {result: 'untested'},
547
+ xtls: {result: 'untested'},
548
+ },
549
+ public3: {
550
+ udp: {result: 'unreachable'},
551
+ tcp: {result: 'unreachable'},
552
+ xtls: {result: 'untested'},
553
+ someOtherField: 'any value',
554
+ },
555
+ public4: {
556
+ udp: {result: 'untested'},
557
+ tcp: {result: 'unreachable'},
558
+ xtls: {result: 'untested'},
559
+ isVideoMesh: false,
560
+ someOtherField: 'any value',
561
+ },
562
+ public5: {
563
+ udp: {result: 'reachable', latencyInMilliseconds: '400', clientMediaIPs: ['10.10.10.10']},
564
+ tcp: {result: 'untested'},
565
+ xtls: {result: 'untested'},
566
+ },
567
+ },
568
+ // expected result:
569
+ {
570
+ reachability_public_udp_success: 3,
571
+ reachability_public_udp_failed: 1,
572
+ reachability_public_tcp_success: 1,
573
+ reachability_public_tcp_failed: 2,
574
+ reachability_vmn_udp_success: 0,
575
+ reachability_vmn_udp_failed: 0,
576
+ reachability_vmn_tcp_success: 0,
577
+ reachability_vmn_tcp_failed: 0,
578
+ }
579
+ );
580
+ });
581
+
582
+ it('returns correct stats when only video mesh nodes were tested', async () => {
583
+ await runCheck(
584
+ // mock storage:
585
+ {
586
+ vmn1: {
587
+ udp: {result: 'unreachable'},
588
+ tcp: {result: 'reachable', latencyInMilliseconds: 100, clientMediaIPs: ['10.10.10.10']},
589
+ xtls: {result: 'untested'},
590
+ isVideoMesh: true,
591
+ },
592
+ vmn2: {
593
+ udp: {result: 'reachable', latencyInMilliseconds: 200, clientMediaIPs: ['10.10.10.10']},
594
+ tcp: {result: 'untested'},
595
+ xtls: {result: 'untested'},
596
+ isVideoMesh: true,
597
+ },
598
+ vmn3: {
599
+ udp: {result: 'reachable', latencyInMilliseconds: 300, clientMediaIPs: ['10.10.10.10']},
600
+ tcp: {result: 'unreachable'},
601
+ xtls: {result: 'untested'},
602
+ isVideoMesh: true,
603
+ },
604
+ vmn4: {
605
+ udp: {result: 'untested'},
606
+ tcp: {result: 'unreachable'},
607
+ xtls: {result: 'untested'},
608
+ isVideoMesh: true,
609
+ someOtherField: 'any value',
610
+ },
611
+ vmn5: {
612
+ udp: {result: 'reachable', latencyInMilliseconds: 200, clientMediaIPs: ['10.10.10.10']},
613
+ tcp: {result: 'unreachable'},
614
+ xtls: {result: 'untested'},
615
+ isVideoMesh: true,
616
+ someOtherField: 'any value',
617
+ },
618
+ },
619
+ // expected result:
620
+ {
621
+ reachability_public_udp_success: 0,
622
+ reachability_public_udp_failed: 0,
623
+ reachability_public_tcp_success: 0,
624
+ reachability_public_tcp_failed: 0,
625
+ reachability_vmn_udp_success: 3,
626
+ reachability_vmn_udp_failed: 1,
627
+ reachability_vmn_tcp_success: 1,
628
+ reachability_vmn_tcp_failed: 3,
629
+ }
630
+ );
631
+ });
632
+ });
@@ -3,6 +3,7 @@ import {assert} from '@webex/test-helper-chai';
3
3
  import MockWebex from '@webex/test-helper-mock-webex';
4
4
  import Meetings from '@webex/plugin-meetings';
5
5
  import ReachabilityRequest from '@webex/plugin-meetings/src/reachability/request';
6
+ import {IP_VERSION} from '@webex/plugin-meetings/src/constants';
6
7
 
7
8
 
8
9
  describe('plugin-meetings/reachability', () => {
@@ -47,7 +48,7 @@ describe('plugin-meetings/reachability', () => {
47
48
  }
48
49
  }));
49
50
 
50
- const res = await reachabilityRequest.getClusters();
51
+ const res = await reachabilityRequest.getClusters(IP_VERSION.only_ipv4);
51
52
 
52
53
  const requestParams = webex.request.getCall(0).args[0];
53
54
 
@@ -58,6 +59,7 @@ describe('plugin-meetings/reachability', () => {
58
59
 
59
60
  assert.deepEqual(requestParams.qs, {
60
61
  JCSupport: 1,
62
+ ipver: 4,
61
63
  });
62
64
  assert.deepEqual(res.clusters.clusterId, {udp: "testUDP", isVideoMesh: true})
63
65
  assert.deepEqual(res.joinCookie, {anycastEntryPoint: "aws-eu-west-1"})
@@ -0,0 +1,40 @@
1
+ import {assert} from '@webex/test-helper-chai';
2
+
3
+ import {convertStunUrlToTurn} from '@webex/plugin-meetings/src/reachability/util';
4
+
5
+ describe('plugin-meetings/src/reachability/util', () => {
6
+ describe('#convertStunUrlToTurn()', () => {
7
+ [
8
+ {
9
+ title: 'a stun url with port',
10
+ stunUrl: 'stun:external-media91.public.wjfkm-a-10.prod.infra.webex.com:5004',
11
+ expectedUrlPart: 'external-media91.public.wjfkm-a-10.prod.infra.webex.com:5004',
12
+ },
13
+ {
14
+ title: 'a stun url without port',
15
+ stunUrl: 'stun:something.somewhere.com',
16
+ expectedUrlPart: 'something.somewhere.com',
17
+ },
18
+ ].forEach(({title, stunUrl, expectedUrlPart}) => {
19
+ it(`should convert ${title} to a TCP turn url`, () => {
20
+ const turnUrl = convertStunUrlToTurn(stunUrl, 'tcp');
21
+
22
+ assert.equal(turnUrl, `turn:${expectedUrlPart}?transport=tcp`);
23
+ });
24
+
25
+ it(`should convert ${title} to a UDP turn url`, () => {
26
+ const turnUrl = convertStunUrlToTurn(stunUrl, 'udp');
27
+
28
+ assert.equal(turnUrl, `turn:${expectedUrlPart}`);
29
+ });
30
+ });
31
+
32
+ it('show fail if stunUrl is not a valid url', () => {
33
+ assert.throws(() => convertStunUrlToTurn('not a url', 'tcp'), 'Invalid URL: not a url');
34
+ });
35
+
36
+ it('show fail if stunUrl is not a STUN url', () => {
37
+ assert.throws(() => convertStunUrlToTurn('http://webex.com', 'tcp'), 'Not a STUN URL: http://webex.com');
38
+ });
39
+ });
40
+ });