@webex/plugin-meetings 3.0.0-beta.34 → 3.0.0-beta.340

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