@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,114 +1,255 @@
1
- import {assert} from '@webex/test-helper-chai';
2
1
  import sinon from 'sinon';
2
+ import {assert} from '@webex/test-helper-chai';
3
3
  import MockWebex from '@webex/test-helper-mock-webex';
4
- import Metrics from '@webex/plugin-meetings/src/metrics';
5
-
4
+ import Meetings from '@webex/plugin-meetings';
6
5
  import RoapRequest from '@webex/plugin-meetings/src/roap/request';
7
-
8
-
9
- describe('RoapRequest', () => {
10
- describe('attachRechabilityData', () => {
11
- let webex;
12
-
13
- beforeEach(() => {
14
- webex = new MockWebex();
6
+ import {IP_VERSION, REACHABILITY} from '@webex/plugin-meetings/src/constants';
7
+
8
+ describe('plugin-meetings/roap', () => {
9
+ let roapRequest;
10
+ let webex;
11
+ const locusUrl = 'locusUrl';
12
+
13
+ beforeEach(async () => {
14
+ webex = new MockWebex({
15
+ children: {
16
+ meetings: Meetings,
17
+ },
15
18
  });
16
-
17
- it('attaches the reachability data when it exists', async () => {
18
- // @ts-ignore
19
- const roapRequest = new RoapRequest({}, {parent: webex});
20
19
 
21
- const sdp = {some: 'attribute'};
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
+ device: {
31
+ url: 'url',
32
+ },
33
+ newMetrics: {
34
+ submitClientEvent: sinon.stub()
35
+ },
36
+ };
37
+
38
+ // @ts-ignore
39
+ roapRequest = new RoapRequest({webex});
40
+
41
+ roapRequest.request = sinon.mock().returns(
42
+ Promise.resolve({
43
+ body: {
44
+ locus: {
45
+ roapSeq: '',
46
+ id: '',
47
+ url: 'url/path',
48
+ fullState: {
49
+ lastActive: 'lastActive',
50
+ },
51
+ },
52
+ },
53
+ })
54
+ );
22
55
 
23
- const reachabilitData = {reachability: 'data'};
56
+ await webex.boundedStorage.put(
57
+ REACHABILITY.namespace,
58
+ REACHABILITY.localStorageJoinCookie,
59
+ JSON.stringify({
60
+ anycastEntryPoint: 'aws-eu-west-1',
61
+ })
62
+ );
63
+ await webex.boundedStorage.put(
64
+ REACHABILITY.namespace,
65
+ REACHABILITY.localStorageResult,
66
+ JSON.stringify({
67
+ clusterId: {
68
+ udp: { result: 'reachable', latencyInMilliseconds: 10 },
69
+ tcp: { result: 'unreachable' },
70
+ isVideoMesh: false,
71
+ },
72
+ })
73
+ );
74
+ });
24
75
 
25
- await webex.boundedStorage.put(
26
- 'Reachability',
27
- 'reachability.result',
28
- JSON.stringify(reachabilitData)
29
- );
76
+ describe('#attachReachabilityData', () => {
77
+ it('returns the correct reachability data', async () => {
78
+ const res = await roapRequest.attachReachabilityData({});
79
+
80
+ assert.deepEqual(res.localSdp, {
81
+ reachability: {
82
+ clusterId: {
83
+ udp: {
84
+ reachable: 'true',
85
+ latencyInMilliseconds: '10',
86
+ },
87
+ tcp: {
88
+ reachable: 'false',
89
+ },
90
+ xtls: {
91
+ untested: 'true',
92
+ }
93
+ },
94
+ },
95
+ });
96
+ assert.deepEqual(res.joinCookie, {
97
+ anycastEntryPoint: 'aws-eu-west-1',
98
+ });
99
+ });
30
100
 
31
- const newSdp = await roapRequest.attachRechabilityData(sdp);
101
+ it('handles the case when reachability data does not exist', async () => {
102
+ await webex.boundedStorage.del(REACHABILITY.namespace, REACHABILITY.localStorageJoinCookie);
32
103
 
33
- assert.deepEqual(newSdp, {
104
+ await webex.boundedStorage.del(REACHABILITY.namespace, REACHABILITY.localStorageResult);
105
+ const sdp = {
34
106
  some: 'attribute',
35
- reachability: reachabilitData
36
- })
37
- });
38
-
39
- it('handles the case when realiability data does not exist', async () => {
40
- // @ts-ignore
41
- const roapRequest = new RoapRequest({}, {parent: webex});
107
+ };
42
108
 
43
- const sdp = {some: 'attribute'};
109
+ const result = await roapRequest.attachReachabilityData(sdp);
44
110
 
45
- const newSdp = await roapRequest.attachRechabilityData(sdp);
46
-
47
- assert.deepEqual(newSdp, sdp);
111
+ assert.deepEqual(result, {
112
+ joinCookie: undefined,
113
+ localSdp: {
114
+ some: 'attribute',
115
+ },
116
+ });
48
117
  });
49
118
  });
50
119
 
51
120
  describe('sendRoap', () => {
52
- let webex;
53
-
54
- beforeEach(() => {
55
- webex = new MockWebex();
56
- });
57
-
58
- it('calls attachReliabilityData', async () => {
59
- Metrics.postEvent = sinon.stub();
121
+ it('includes joinCookie in the request correctly', async () => {
122
+ const locusMediaRequest = {send: sinon.stub().resolves({body: {locus: {}}})};
123
+ const ipVersion = IP_VERSION.unknown;
60
124
 
61
- // @ts-ignore
62
- const roapRequest = new RoapRequest({}, {parent: webex});
63
-
64
- const newSdp = {new: 'sdp'}
125
+ await roapRequest.sendRoap({
126
+ locusSelfUrl: locusUrl,
127
+ ipVersion,
128
+ mediaId: 'mediaId',
129
+ roapMessage: {
130
+ seq: 'seq',
131
+ },
132
+ meetingId: 'meeting-id',
133
+ locusMediaRequest,
134
+ });
65
135
 
66
- roapRequest.attachRechabilityData = sinon.stub().returns(Promise.resolve(newSdp));
67
- webex.request.returns(Promise.resolve({
68
- body: {
69
- locus: {}
70
- }
71
- }))
136
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
137
+ name: 'client.locus.media.request',
138
+ options: {
139
+ meetingId: 'meeting-id',
140
+ },
141
+ });
72
142
 
73
- const result = await roapRequest.sendRoap({
74
- roapMessage: {seq: 1},
75
- locusSelfUrl: 'locusSelfUrl',
76
- mediaId: 'mediaId',
77
- correlationId: 'correlationId',
78
- audioMuted: true,
79
- videoMuted: true,
80
- meetingId: 'meetingId',
81
- preferTranscoding: true
143
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
144
+ name: 'client.locus.media.response',
145
+ options: {
146
+ meetingId: 'meeting-id',
147
+ },
82
148
  });
83
149
 
84
- assert.calledOnceWithExactly(webex.request, {
85
- uri: 'locusSelfUrl/media',
86
- method: 'PUT',
87
- body: {
88
- device: {
89
- url: undefined,
90
- deviceType: undefined,
150
+ const requestParams = locusMediaRequest.send.getCall(0).args[0];
151
+ assert.deepEqual(requestParams, {
152
+ type: 'RoapMessage',
153
+ selfUrl: locusUrl,
154
+ ipVersion,
155
+ joinCookie: {
156
+ anycastEntryPoint: 'aws-eu-west-1',
157
+ },
158
+ mediaId: 'mediaId',
159
+ roapMessage: {
160
+ seq: 'seq',
161
+ },
162
+ reachability: {
163
+ clusterId: {
164
+ tcp: {
165
+ reachable: 'false',
166
+ },
167
+ udp: {
168
+ latencyInMilliseconds: '10',
169
+ reachable: 'true',
170
+ },
171
+ xtls: {
172
+ untested: 'true',
173
+ },
91
174
  },
92
- correlationId: 'correlationId',
93
- localMedias: [{
94
- localSdp: JSON.stringify(newSdp),
95
- mediaId: 'mediaId'
96
- }],
97
- clientMediaPreferences: {preferTranscoding: true}
98
175
  },
99
176
  });
177
+ });
100
178
 
101
- assert.calledOnceWithExactly(roapRequest.attachRechabilityData, {
102
- roapMessage: {seq: 1},
103
- audioMuted: true,
104
- videoMuted: true
179
+ it('sends correct client event when fails', async () => {
180
+ const locusMediaRequest = {send: sinon.stub().rejects({code: 300, message: 'error'})};
181
+ try {
182
+ await roapRequest.sendRoap({
183
+ locusSelfUrl: locusUrl,
184
+ mediaId: 'mediaId',
185
+ roapMessage: {
186
+ seq: 'seq',
187
+ },
188
+ meetingId: 'meeting-id',
189
+ locusMediaRequest,
190
+ });
191
+ } catch (err) {
192
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
193
+ name: 'client.locus.media.response',
194
+ options: {
195
+ meetingId: 'meeting-id',
196
+ rawError: {code: 300, message: 'error'},
197
+ },
198
+ });
199
+ }
200
+ });
201
+ });
202
+
203
+ it('calls attachReachabilityData when sendRoap', async () => {
204
+ const locusMediaRequest = { send: sinon.stub().resolves({body: {locus: {}}})};
205
+
206
+ const newSdp = {
207
+ new: 'sdp',
208
+ reachability: { someResult: 'whatever' }
209
+ };
210
+ const ipVersion = IP_VERSION.only_ipv6;
211
+
212
+ roapRequest.attachReachabilityData = sinon.stub().returns(
213
+ Promise.resolve({
214
+ localSdp: newSdp,
215
+ joinCookie: {
216
+ anycastEntryPoint: 'aws-eu-west-1',
217
+ },
105
218
  })
219
+ );
220
+
221
+ await roapRequest.sendRoap({
222
+ roapMessage: {
223
+ seq: 1,
224
+ },
225
+ locusSelfUrl: 'locusSelfUrl',
226
+ ipVersion,
227
+ mediaId: 'mediaId',
228
+ meetingId: 'meetingId',
229
+ preferTranscoding: true,
230
+ locusMediaRequest
231
+ });
106
232
 
107
- assert.deepEqual(result, {
108
- locus: {
109
- roapSeq: 1
110
- }
111
- });
233
+ const requestParams = locusMediaRequest.send.getCall(0).args[0];
234
+
235
+ assert.deepEqual(requestParams, {
236
+ type: 'RoapMessage',
237
+ selfUrl: 'locusSelfUrl',
238
+ ipVersion,
239
+ joinCookie: {
240
+ anycastEntryPoint: 'aws-eu-west-1',
241
+ },
242
+ mediaId: 'mediaId',
243
+ roapMessage: {
244
+ seq: 1,
245
+ },
246
+ reachability: { someResult: 'whatever' },
112
247
  });
113
- })
248
+
249
+ assert.calledOnceWithExactly(roapRequest.attachReachabilityData, {
250
+ roapMessage: {
251
+ seq: 1,
252
+ },
253
+ });
254
+ });
114
255
  });
@@ -5,8 +5,10 @@ import TurnDiscovery from '@webex/plugin-meetings/src/roap/turnDiscovery';
5
5
  import Metrics from '@webex/plugin-meetings/src/metrics';
6
6
  import BEHAVIORAL_METRICS from '@webex/plugin-meetings/src/metrics/constants';
7
7
  import RoapRequest from '@webex/plugin-meetings/src/roap/request';
8
+ import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
8
9
 
9
10
  import testUtils from '../../../utils/testUtils';
11
+ import { IP_VERSION } from '../../../../src/constants';
10
12
 
11
13
  describe('TurnDiscovery', () => {
12
14
  let clock;
@@ -23,6 +25,7 @@ describe('TurnDiscovery', () => {
23
25
  clock = sinon.useFakeTimers();
24
26
 
25
27
  sinon.stub(Metrics, 'sendBehavioralMetric');
28
+ sinon.stub(MeetingUtil, 'getIpVersion').returns(IP_VERSION.unknown);
26
29
 
27
30
  mockRoapRequest = {
28
31
  sendRoap: sinon.fake.resolves({mediaConnections: FAKE_MEDIA_CONNECTIONS_FROM_LOCUS}),
@@ -30,11 +33,6 @@ describe('TurnDiscovery', () => {
30
33
 
31
34
  testMeeting = {
32
35
  id: 'fake meeting id',
33
- config: {
34
- experimental: {
35
- enableTurnDiscovery: true,
36
- },
37
- },
38
36
  correlationId: 'fake correlation id',
39
37
  selfUrl: 'fake self url',
40
38
  mediaId: 'fake media id',
@@ -50,8 +48,11 @@ describe('TurnDiscovery', () => {
50
48
  testMeeting.roapSeq = newSeq;
51
49
  }),
52
50
  updateMediaConnections: sinon.stub(),
53
- webex: {meetings: {reachability: {isAnyClusterReachable: () => Promise.resolve(false)}}},
54
- isMultistream: false
51
+ webex: {meetings: {reachability: {
52
+ isAnyPublicClusterReachable: () => Promise.resolve(false),
53
+ }}},
54
+ isMultistream: false,
55
+ locusMediaRequest: { fake: true },
55
56
  };
56
57
  });
57
58
 
@@ -68,20 +69,24 @@ describe('TurnDiscovery', () => {
68
69
  await testUtils.flushPromises();
69
70
 
70
71
  assert.calledOnce(mockRoapRequest.sendRoap);
71
- assert.calledWith(mockRoapRequest.sendRoap, {
72
+
73
+ const expectedSendRoapArgs: any = {
72
74
  roapMessage: {
73
75
  messageType,
74
76
  version: '2',
75
77
  seq: expectedSeq,
76
78
  },
77
- correlationId: testMeeting.correlationId,
78
79
  locusSelfUrl: testMeeting.selfUrl,
79
80
  mediaId: expectedMediaId,
80
- audioMuted: testMeeting.audio?.isLocallyMuted(),
81
- videoMuted: testMeeting.video?.isLocallyMuted(),
82
81
  meetingId: testMeeting.id,
83
- preferTranscoding: !testMeeting.isMultistream
84
- });
82
+ locusMediaRequest: testMeeting.locusMediaRequest,
83
+ };
84
+
85
+ if (messageType === 'TURN_DISCOVERY_REQUEST') {
86
+ expectedSendRoapArgs.ipVersion = 0;
87
+ }
88
+
89
+ assert.calledWith(mockRoapRequest.sendRoap, expectedSendRoapArgs);
85
90
 
86
91
  if (messageType === 'TURN_DISCOVERY_REQUEST') {
87
92
  // check also that we've applied the media connections from the response
@@ -143,6 +148,44 @@ describe('TurnDiscovery', () => {
143
148
  });
144
149
  });
145
150
 
151
+ it('sends TURN_DISCOVERY_REQUEST, waits for response and sends OK when isForced = true when cluster is reachable', async () => {
152
+ const prev = testMeeting.webex.meetings.reachability.isAnyPublicClusterReachable;
153
+ testMeeting.webex.meetings.reachability.isAnyPublicClusterReachable = sinon.stub().resolves(true);
154
+
155
+ const td = new TurnDiscovery(mockRoapRequest);
156
+ const result = td.doTurnDiscovery(testMeeting, false, true);
157
+
158
+ // We ignore reachability results so we don't get skip reason
159
+ assert.notCalled(testMeeting.webex.meetings.reachability.isAnyPublicClusterReachable);
160
+
161
+ // check that TURN_DISCOVERY_REQUEST was sent
162
+ await checkRoapMessageSent('TURN_DISCOVERY_REQUEST', 0);
163
+ // @ts-ignore
164
+ mockRoapRequest.sendRoap.resetHistory();
165
+ // simulate the response
166
+ td.handleTurnDiscoveryResponse({
167
+ headers: [
168
+ `x-cisco-turn-url=${FAKE_TURN_URL}`,
169
+ `x-cisco-turn-username=${FAKE_TURN_USERNAME}`,
170
+ `x-cisco-turn-password=${FAKE_TURN_PASSWORD}`,
171
+ ]
172
+ });
173
+ await testUtils.flushPromises();
174
+ // check that we've sent OK
175
+ await checkRoapMessageSent('OK', 0);
176
+
177
+ const {turnServerInfo, turnDiscoverySkippedReason} = await result;
178
+ assert.deepEqual(turnServerInfo, {
179
+ url: FAKE_TURN_URL,
180
+ username: FAKE_TURN_USERNAME,
181
+ password: FAKE_TURN_PASSWORD
182
+ });
183
+ assert.isUndefined(turnDiscoverySkippedReason);
184
+
185
+ // restore previous callback
186
+ testMeeting.webex.meetings.reachability.isAnyPublicClusterReachable = prev;
187
+ });
188
+
146
189
  it('sends TURN_DISCOVERY_REQUEST with empty mediaId when isReconnecting is true', async () => {
147
190
  const td = new TurnDiscovery(mockRoapRequest);
148
191
 
@@ -214,24 +257,6 @@ describe('TurnDiscovery', () => {
214
257
  assert.isUndefined(turnDiscoverySkippedReason);
215
258
  });
216
259
 
217
- it('resolves with undefined if turn discovery feature is disabled in config', async () => {
218
- const prevConfigValue = testMeeting.config.experimental.enableTurnDiscovery;
219
-
220
- testMeeting.config.experimental.enableTurnDiscovery = false;
221
- // @ts-ignore
222
- const result = await new TurnDiscovery(mockRoapRequest).doTurnDiscovery(testMeeting);
223
-
224
- const {turnServerInfo, turnDiscoverySkippedReason} = result;
225
-
226
- assert.isUndefined(turnServerInfo);
227
- assert.equal(turnDiscoverySkippedReason, 'config');
228
- assert.notCalled(mockRoapRequest.sendRoap);
229
- assert.notCalled(Metrics.sendBehavioralMetric);
230
-
231
- // restore previous config
232
- testMeeting.config.experimental.enableTurnDiscovery = prevConfigValue;
233
- });
234
-
235
260
  it('resolves with undefined if sending the request fails', async () => {
236
261
  const td = new TurnDiscovery(mockRoapRequest);
237
262
 
@@ -247,8 +272,8 @@ describe('TurnDiscovery', () => {
247
272
  });
248
273
 
249
274
  it('resolves with undefined when cluster is reachable', async () => {
250
- const prev = testMeeting.webex.meetings.reachability.isAnyClusterReachable;
251
- testMeeting.webex.meetings.reachability.isAnyClusterReachable = () => Promise.resolve(true);
275
+ const prev = testMeeting.webex.meetings.reachability.isAnyPublicClusterReachable;
276
+ testMeeting.webex.meetings.reachability.isAnyPublicClusterReachable = () => Promise.resolve(true);
252
277
  const result = await new TurnDiscovery(mockRoapRequest).doTurnDiscovery(testMeeting);
253
278
 
254
279
  const {turnServerInfo, turnDiscoverySkippedReason} = result;
@@ -257,7 +282,7 @@ describe('TurnDiscovery', () => {
257
282
  assert.equal(turnDiscoverySkippedReason, 'reachability');
258
283
  assert.notCalled(mockRoapRequest.sendRoap);
259
284
  assert.notCalled(Metrics.sendBehavioralMetric);
260
- testMeeting.webex.meetings.reachability.isAnyClusterReachable = prev;
285
+ testMeeting.webex.meetings.reachability.isAnyPublicClusterReachable = prev;
261
286
  });
262
287
 
263
288
  it("resolves with undefined if we don't get a response within 10s", async () => {
@@ -367,6 +392,23 @@ describe('TurnDiscovery', () => {
367
392
  });
368
393
  });
369
394
 
395
+ describe('isSkipped', () => {
396
+ [
397
+ {isAnyPublicClusterReachable: true, expectedIsSkipped: true},
398
+ {isAnyPublicClusterReachable: false, expectedIsSkipped: false},
399
+ ].forEach(({isAnyPublicClusterReachable, expectedIsSkipped}) => {
400
+ it(`returns ${expectedIsSkipped} when isAnyPublicClusterReachable() returns ${isAnyPublicClusterReachable ? 'true' : 'false'}`, async () => {
401
+ sinon.stub(testMeeting.webex.meetings.reachability, 'isAnyPublicClusterReachable').resolves(isAnyPublicClusterReachable);
402
+
403
+ const td = new TurnDiscovery(mockRoapRequest);
404
+
405
+ const isSkipped = await td.isSkipped(testMeeting);
406
+
407
+ assert.equal(isSkipped, expectedIsSkipped);
408
+ })
409
+ })
410
+ })
411
+
370
412
  describe('handleTurnDiscoveryResponse', () => {
371
413
  it("doesn't do anything if turn discovery was not started", () => {
372
414
  const td = new TurnDiscovery(mockRoapRequest);
@@ -0,0 +1,93 @@
1
+ import RtcMetrics from '@webex/plugin-meetings/src/rtcMetrics';
2
+ import MockWebex from '@webex/test-helper-mock-webex';
3
+ import {assert} from '@webex/test-helper-chai';
4
+ import sinon from 'sinon';
5
+ import RTC_METRICS from '../../../../src/rtcMetrics/constants';
6
+
7
+ const FAKE_METRICS_ITEM = {payload: ['fake-metrics']};
8
+
9
+ const STATS_WITH_IP = '{\"id\":\"RTCIceCandidate_/kQs0ZNU\",\"type\":\"remote-candidate\",\"transportId\":\"RTCTransport_0_1\",\"isRemote\":true,\"ip\":\"11.22.111.255\",\"address\":\"11.22.111.255\",\"port\":5004,\"protocol\":\"udp\",\"candidateType\":\"host\",\"priority\":2130706431}';
10
+ const STATS_WITH_IP_RESULT = '{\"id\":\"RTCIceCandidate_/kQs0ZNU\",\"type\":\"remote-candidate\",\"transportId\":\"RTCTransport_0_1\",\"isRemote\":true,\"ip\":\"11.22.111.240\",\"address\":\"11.22.111.240\",\"port\":5004,\"protocol\":\"udp\",\"candidateType\":\"host\",\"priority\":2130706431}';
11
+
12
+ describe('RtcMetrics', () => {
13
+ let metrics: RtcMetrics;
14
+ let webex: MockWebex;
15
+ let clock;
16
+ let anonymizeIpSpy;
17
+
18
+ const sandbox = sinon.createSandbox();
19
+
20
+ beforeEach(() => {
21
+ clock = sinon.useFakeTimers();
22
+ webex = new MockWebex();
23
+ metrics = new RtcMetrics(webex, 'mock-meeting-id', 'mock-correlation-id');
24
+ anonymizeIpSpy = sandbox.spy(metrics, 'anonymizeIp');
25
+ });
26
+
27
+ afterEach(() => {
28
+ sandbox.restore();
29
+ });
30
+
31
+ it('sendMetrics should send a webex request', () => {
32
+ assert.notCalled(webex.request);
33
+
34
+ metrics.addMetrics(FAKE_METRICS_ITEM);
35
+ (metrics as any).sendMetrics();
36
+
37
+ assert.callCount(webex.request, 1);
38
+ assert.calledWithMatch(webex.request, sinon.match.has('headers', {
39
+ type: 'webrtcMedia',
40
+ appId: RTC_METRICS.APP_ID,
41
+ }));
42
+ assert.calledWithMatch(webex.request, sinon.match.hasNested('body.metrics[0].data[0].payload', FAKE_METRICS_ITEM.payload));
43
+ assert.calledWithMatch(webex.request, sinon.match.hasNested('body.metrics[0].meetingId', 'mock-meeting-id'));
44
+ assert.calledWithMatch(webex.request, sinon.match.hasNested('body.metrics[0].correlationId', 'mock-correlation-id'));
45
+ });
46
+
47
+ it('should have a defined sendMetricsInQueue function which is public', () => {
48
+ assert.isDefined(metrics.sendMetricsInQueue);
49
+ assert.isFunction(metrics.sendMetricsInQueue);
50
+ });
51
+
52
+ it('should send metrics requests over time', () => {
53
+ assert.notCalled(webex.request);
54
+
55
+ metrics.addMetrics(FAKE_METRICS_ITEM);
56
+ assert.deepEqual(metrics.metricsQueue, [FAKE_METRICS_ITEM]);
57
+ clock.tick(60 * 1000);
58
+
59
+ assert.callCount(webex.request, 1);
60
+ });
61
+
62
+ it('should not send requests with no items in the queue', () => {
63
+ clock.tick(60 * 1000);
64
+ assert.notCalled(webex.request);
65
+ });
66
+
67
+ it('sendMetricsInQueue should send metrics if any exist in the queue', () => {
68
+ assert.notCalled(webex.request);
69
+
70
+ metrics.addMetrics(FAKE_METRICS_ITEM);
71
+ (metrics as any).sendMetricsInQueue();
72
+
73
+ assert.callCount(webex.request, 1);
74
+ });
75
+
76
+ it('should clear out metrics on close', () => {
77
+ assert.notCalled(webex.request);
78
+
79
+ metrics.addMetrics(FAKE_METRICS_ITEM);
80
+ metrics.closeMetrics();
81
+
82
+ assert.callCount(webex.request, 1);
83
+ });
84
+
85
+ it('should anonymize IP addresses', () => {
86
+ assert.strictEqual(metrics.anonymizeIp(STATS_WITH_IP), STATS_WITH_IP_RESULT);
87
+ });
88
+
89
+ it('should call anonymizeIp', () => {
90
+ metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
91
+ assert.calledOnce(anonymizeIpSpy);
92
+ })
93
+ });