@webex/plugin-meetings 3.0.0-beta.17 → 3.0.0-beta.171

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 (427) hide show
  1. package/README.md +45 -7
  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 +359 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +216 -0
  9. package/dist/breakouts/breakout.js.map +1 -0
  10. package/dist/breakouts/collection.js +23 -0
  11. package/dist/breakouts/collection.js.map +1 -0
  12. package/dist/breakouts/edit-lock-error.js +52 -0
  13. package/dist/breakouts/edit-lock-error.js.map +1 -0
  14. package/dist/breakouts/events.js +45 -0
  15. package/dist/breakouts/events.js.map +1 -0
  16. package/dist/breakouts/index.js +1048 -0
  17. package/dist/breakouts/index.js.map +1 -0
  18. package/dist/breakouts/request.js +78 -0
  19. package/dist/breakouts/request.js.map +1 -0
  20. package/dist/breakouts/utils.js +67 -0
  21. package/dist/breakouts/utils.js.map +1 -0
  22. package/dist/common/errors/webex-errors.js +3 -2
  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/config.js +6 -8
  27. package/dist/config.js.map +1 -1
  28. package/dist/constants.js +194 -28
  29. package/dist/constants.js.map +1 -1
  30. package/dist/controls-options-manager/constants.js +14 -0
  31. package/dist/controls-options-manager/constants.js.map +1 -0
  32. package/dist/controls-options-manager/enums.js +27 -0
  33. package/dist/controls-options-manager/enums.js.map +1 -0
  34. package/dist/controls-options-manager/index.js +297 -0
  35. package/dist/controls-options-manager/index.js.map +1 -0
  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 +300 -0
  39. package/dist/controls-options-manager/util.js.map +1 -0
  40. package/dist/index.js +107 -0
  41. package/dist/index.js.map +1 -1
  42. package/dist/interpretation/collection.js +23 -0
  43. package/dist/interpretation/collection.js.map +1 -0
  44. package/dist/interpretation/index.js +214 -0
  45. package/dist/interpretation/index.js.map +1 -0
  46. package/dist/interpretation/siLanguage.js +25 -0
  47. package/dist/interpretation/siLanguage.js.map +1 -0
  48. package/dist/locus-info/controlsUtils.js +92 -2
  49. package/dist/locus-info/controlsUtils.js.map +1 -1
  50. package/dist/locus-info/index.js +350 -41
  51. package/dist/locus-info/index.js.map +1 -1
  52. package/dist/locus-info/mediaSharesUtils.js +43 -1
  53. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  54. package/dist/locus-info/parser.js +2 -1
  55. package/dist/locus-info/parser.js.map +1 -1
  56. package/dist/locus-info/selfUtils.js +97 -14
  57. package/dist/locus-info/selfUtils.js.map +1 -1
  58. package/dist/media/index.js +41 -136
  59. package/dist/media/index.js.map +1 -1
  60. package/dist/media/properties.js +33 -94
  61. package/dist/media/properties.js.map +1 -1
  62. package/dist/mediaQualityMetrics/config.js +505 -493
  63. package/dist/mediaQualityMetrics/config.js.map +1 -1
  64. package/dist/meeting/in-meeting-actions.js +76 -2
  65. package/dist/meeting/in-meeting-actions.js.map +1 -1
  66. package/dist/meeting/index.js +2757 -2439
  67. package/dist/meeting/index.js.map +1 -1
  68. package/dist/meeting/locusMediaRequest.js +291 -0
  69. package/dist/meeting/locusMediaRequest.js.map +1 -0
  70. package/dist/meeting/muteState.js +229 -124
  71. package/dist/meeting/muteState.js.map +1 -1
  72. package/dist/meeting/request.js +191 -167
  73. package/dist/meeting/request.js.map +1 -1
  74. package/dist/meeting/request.type.js.map +1 -1
  75. package/dist/meeting/util.js +477 -466
  76. package/dist/meeting/util.js.map +1 -1
  77. package/dist/meeting-info/index.js +48 -7
  78. package/dist/meeting-info/index.js.map +1 -1
  79. package/dist/meeting-info/meeting-info-v2.js +172 -50
  80. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  81. package/dist/meeting-info/utilv2.js +20 -5
  82. package/dist/meeting-info/utilv2.js.map +1 -1
  83. package/dist/meetings/collection.js +22 -0
  84. package/dist/meetings/collection.js.map +1 -1
  85. package/dist/meetings/index.js +377 -82
  86. package/dist/meetings/index.js.map +1 -1
  87. package/dist/meetings/meetings.types.js +7 -0
  88. package/dist/meetings/meetings.types.js.map +1 -0
  89. package/dist/meetings/request.js +16 -12
  90. package/dist/meetings/request.js.map +1 -1
  91. package/dist/meetings/util.js +88 -1
  92. package/dist/meetings/util.js.map +1 -1
  93. package/dist/member/index.js +43 -0
  94. package/dist/member/index.js.map +1 -1
  95. package/dist/member/types.js +15 -0
  96. package/dist/member/types.js.map +1 -0
  97. package/dist/member/util.js +97 -3
  98. package/dist/member/util.js.map +1 -1
  99. package/dist/members/collection.js +10 -0
  100. package/dist/members/collection.js.map +1 -1
  101. package/dist/members/index.js +94 -11
  102. package/dist/members/index.js.map +1 -1
  103. package/dist/members/request.js +109 -39
  104. package/dist/members/request.js.map +1 -1
  105. package/dist/members/types.js +15 -0
  106. package/dist/members/types.js.map +1 -0
  107. package/dist/members/util.js +316 -233
  108. package/dist/members/util.js.map +1 -1
  109. package/dist/metrics/constants.js +3 -5
  110. package/dist/metrics/constants.js.map +1 -1
  111. package/dist/metrics/index.js +1 -468
  112. package/dist/metrics/index.js.map +1 -1
  113. package/dist/multistream/mediaRequestManager.js +265 -36
  114. package/dist/multistream/mediaRequestManager.js.map +1 -1
  115. package/dist/multistream/receiveSlot.js +52 -19
  116. package/dist/multistream/receiveSlot.js.map +1 -1
  117. package/dist/multistream/receiveSlotManager.js +53 -33
  118. package/dist/multistream/receiveSlotManager.js.map +1 -1
  119. package/dist/multistream/remoteMedia.js +44 -18
  120. package/dist/multistream/remoteMedia.js.map +1 -1
  121. package/dist/multistream/remoteMediaGroup.js +60 -3
  122. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  123. package/dist/multistream/remoteMediaManager.js +322 -103
  124. package/dist/multistream/remoteMediaManager.js.map +1 -1
  125. package/dist/networkQualityMonitor/index.js +4 -2
  126. package/dist/networkQualityMonitor/index.js.map +1 -1
  127. package/dist/reachability/index.js +117 -60
  128. package/dist/reachability/index.js.map +1 -1
  129. package/dist/reachability/request.js +12 -5
  130. package/dist/reachability/request.js.map +1 -1
  131. package/dist/reactions/constants.js +13 -0
  132. package/dist/reactions/constants.js.map +1 -0
  133. package/dist/reactions/reactions.js +2 -2
  134. package/dist/reactions/reactions.js.map +1 -1
  135. package/dist/reactions/reactions.type.js +18 -18
  136. package/dist/reactions/reactions.type.js.map +1 -1
  137. package/dist/reconnection-manager/index.js +216 -162
  138. package/dist/reconnection-manager/index.js.map +1 -1
  139. package/dist/recording-controller/enums.js +17 -0
  140. package/dist/recording-controller/enums.js.map +1 -0
  141. package/dist/recording-controller/index.js +363 -0
  142. package/dist/recording-controller/index.js.map +1 -0
  143. package/dist/recording-controller/util.js +64 -0
  144. package/dist/recording-controller/util.js.map +1 -0
  145. package/dist/roap/index.js +21 -29
  146. package/dist/roap/index.js.map +1 -1
  147. package/dist/roap/request.js +135 -94
  148. package/dist/roap/request.js.map +1 -1
  149. package/dist/roap/turnDiscovery.js +135 -53
  150. package/dist/roap/turnDiscovery.js.map +1 -1
  151. package/dist/statsAnalyzer/global.js +1 -93
  152. package/dist/statsAnalyzer/global.js.map +1 -1
  153. package/dist/statsAnalyzer/index.js +329 -314
  154. package/dist/statsAnalyzer/index.js.map +1 -1
  155. package/dist/statsAnalyzer/mqaUtil.js +103 -54
  156. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  157. package/dist/types/annotation/annotation.types.d.ts +43 -0
  158. package/dist/types/annotation/constants.d.ts +31 -0
  159. package/dist/types/annotation/index.d.ts +124 -0
  160. package/dist/types/breakouts/breakout.d.ts +8 -0
  161. package/dist/types/breakouts/collection.d.ts +5 -0
  162. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  163. package/dist/types/breakouts/events.d.ts +8 -0
  164. package/dist/types/breakouts/index.d.ts +5 -0
  165. package/dist/types/breakouts/request.d.ts +22 -0
  166. package/dist/types/breakouts/utils.d.ts +15 -0
  167. package/dist/types/common/browser-detection.d.ts +9 -0
  168. package/dist/types/common/collection.d.ts +48 -0
  169. package/dist/types/common/config.d.ts +2 -0
  170. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  171. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  172. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  173. package/dist/types/common/errors/media.d.ts +15 -0
  174. package/dist/types/common/errors/parameter.d.ts +15 -0
  175. package/dist/types/common/errors/password-error.d.ts +15 -0
  176. package/dist/types/common/errors/permission.d.ts +14 -0
  177. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  178. package/dist/types/common/errors/reconnection.d.ts +15 -0
  179. package/dist/types/common/errors/stats.d.ts +15 -0
  180. package/dist/types/common/errors/webex-errors.d.ts +69 -0
  181. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  182. package/dist/types/common/events/events-scope.d.ts +17 -0
  183. package/dist/types/common/events/events.d.ts +12 -0
  184. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  185. package/dist/types/common/events/util.d.ts +2 -0
  186. package/dist/types/common/logs/logger-config.d.ts +2 -0
  187. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  188. package/dist/types/common/logs/request.d.ts +34 -0
  189. package/dist/types/common/queue.d.ts +32 -0
  190. package/dist/types/config.d.ts +72 -0
  191. package/dist/types/constants.d.ts +1007 -0
  192. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  193. package/dist/types/controls-options-manager/enums.d.ts +15 -0
  194. package/dist/types/controls-options-manager/index.d.ts +136 -0
  195. package/dist/types/controls-options-manager/types.d.ts +43 -0
  196. package/dist/types/controls-options-manager/util.d.ts +1 -0
  197. package/dist/types/index.d.ts +7 -0
  198. package/dist/types/interpretation/collection.d.ts +5 -0
  199. package/dist/types/interpretation/index.d.ts +5 -0
  200. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  201. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  202. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  203. package/dist/types/locus-info/fullState.d.ts +2 -0
  204. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  205. package/dist/types/locus-info/index.d.ts +315 -0
  206. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  207. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  208. package/dist/types/locus-info/parser.d.ts +212 -0
  209. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  210. package/dist/types/media/index.d.ts +34 -0
  211. package/dist/types/media/properties.d.ts +93 -0
  212. package/dist/types/media/util.d.ts +2 -0
  213. package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
  214. package/dist/types/meeting/in-meeting-actions.d.ts +149 -0
  215. package/dist/types/meeting/index.d.ts +1462 -0
  216. package/dist/types/meeting/locusMediaRequest.d.ts +70 -0
  217. package/dist/types/meeting/muteState.d.ts +184 -0
  218. package/dist/types/meeting/request.d.ts +270 -0
  219. package/dist/types/meeting/request.type.d.ts +11 -0
  220. package/dist/types/meeting/state.d.ts +9 -0
  221. package/dist/types/meeting/util.d.ts +77 -0
  222. package/dist/types/meeting-info/collection.d.ts +20 -0
  223. package/dist/types/meeting-info/index.d.ts +62 -0
  224. package/dist/types/meeting-info/meeting-info-v2.d.ts +122 -0
  225. package/dist/types/meeting-info/request.d.ts +22 -0
  226. package/dist/types/meeting-info/util.d.ts +2 -0
  227. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  228. package/dist/types/meetings/collection.d.ts +31 -0
  229. package/dist/types/meetings/index.d.ts +365 -0
  230. package/dist/types/meetings/meetings.types.d.ts +4 -0
  231. package/dist/types/meetings/request.d.ts +27 -0
  232. package/dist/types/meetings/util.d.ts +18 -0
  233. package/dist/types/member/index.d.ts +158 -0
  234. package/dist/types/member/types.d.ts +21 -0
  235. package/dist/types/member/util.d.ts +2 -0
  236. package/dist/types/members/collection.d.ts +29 -0
  237. package/dist/types/members/index.d.ts +353 -0
  238. package/dist/types/members/request.d.ts +114 -0
  239. package/dist/types/members/types.d.ts +24 -0
  240. package/dist/types/members/util.d.ts +210 -0
  241. package/dist/types/metrics/constants.d.ts +55 -0
  242. package/dist/types/metrics/index.d.ts +45 -0
  243. package/dist/types/multistream/mediaRequestManager.d.ts +118 -0
  244. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  245. package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
  246. package/dist/types/multistream/remoteMedia.d.ts +72 -0
  247. package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
  248. package/dist/types/multistream/remoteMediaManager.d.ts +277 -0
  249. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  250. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  251. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  252. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  253. package/dist/types/reachability/index.d.ts +152 -0
  254. package/dist/types/reachability/request.d.ts +37 -0
  255. package/dist/types/reactions/constants.d.ts +3 -0
  256. package/dist/types/reactions/reactions.d.ts +4 -0
  257. package/dist/types/reactions/reactions.type.d.ts +52 -0
  258. package/dist/types/reconnection-manager/index.d.ts +126 -0
  259. package/dist/types/recording-controller/enums.d.ts +7 -0
  260. package/dist/types/recording-controller/index.d.ts +208 -0
  261. package/dist/types/recording-controller/util.d.ts +14 -0
  262. package/dist/types/roap/index.d.ts +77 -0
  263. package/dist/types/roap/request.d.ts +36 -0
  264. package/dist/types/roap/turnDiscovery.d.ts +91 -0
  265. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  266. package/dist/types/statsAnalyzer/index.d.ts +200 -0
  267. package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
  268. package/dist/types/transcription/index.d.ts +64 -0
  269. package/package.json +29 -21
  270. package/src/annotation/annotation.types.ts +52 -0
  271. package/src/annotation/constants.ts +36 -0
  272. package/src/annotation/index.ts +343 -0
  273. package/src/breakouts/README.md +220 -0
  274. package/src/breakouts/breakout.ts +188 -0
  275. package/src/breakouts/collection.ts +19 -0
  276. package/src/breakouts/edit-lock-error.ts +25 -0
  277. package/src/breakouts/events.ts +56 -0
  278. package/src/breakouts/index.ts +925 -0
  279. package/src/breakouts/request.ts +55 -0
  280. package/src/breakouts/utils.ts +57 -0
  281. package/src/common/errors/webex-errors.ts +6 -2
  282. package/src/common/logs/logger-proxy.ts +1 -1
  283. package/src/config.ts +5 -7
  284. package/src/constants.ts +183 -22
  285. package/src/controls-options-manager/constants.ts +5 -0
  286. package/src/controls-options-manager/enums.ts +18 -0
  287. package/src/controls-options-manager/index.ts +278 -0
  288. package/src/controls-options-manager/types.ts +59 -0
  289. package/src/controls-options-manager/util.ts +286 -0
  290. package/src/index.ts +39 -0
  291. package/src/interpretation/README.md +51 -0
  292. package/src/interpretation/collection.ts +19 -0
  293. package/src/interpretation/index.ts +182 -0
  294. package/src/interpretation/siLanguage.ts +18 -0
  295. package/src/locus-info/controlsUtils.ts +110 -0
  296. package/src/locus-info/index.ts +374 -38
  297. package/src/locus-info/mediaSharesUtils.ts +48 -0
  298. package/src/locus-info/parser.ts +2 -1
  299. package/src/locus-info/selfUtils.ts +86 -2
  300. package/src/media/index.ts +78 -144
  301. package/src/media/properties.ts +55 -99
  302. package/src/mediaQualityMetrics/config.ts +379 -377
  303. package/src/meeting/in-meeting-actions.ts +151 -3
  304. package/src/meeting/index.ts +2181 -2052
  305. package/src/meeting/locusMediaRequest.ts +309 -0
  306. package/src/meeting/muteState.ts +228 -132
  307. package/src/meeting/request.ts +100 -91
  308. package/src/meeting/request.type.ts +2 -0
  309. package/src/meeting/util.ts +450 -439
  310. package/src/meeting-info/index.ts +54 -8
  311. package/src/meeting-info/meeting-info-v2.ts +150 -14
  312. package/src/meeting-info/utilv2.ts +13 -3
  313. package/src/meetings/collection.ts +20 -0
  314. package/src/meetings/index.ts +396 -89
  315. package/src/meetings/meetings.types.ts +12 -0
  316. package/src/meetings/request.ts +3 -1
  317. package/src/meetings/util.ts +103 -4
  318. package/src/member/index.ts +42 -0
  319. package/src/member/types.ts +24 -0
  320. package/src/member/util.ts +95 -1
  321. package/src/members/collection.ts +8 -0
  322. package/src/members/index.ts +108 -6
  323. package/src/members/request.ts +98 -17
  324. package/src/members/types.ts +28 -0
  325. package/src/members/util.ts +319 -240
  326. package/src/metrics/constants.ts +2 -4
  327. package/src/metrics/index.ts +1 -490
  328. package/src/multistream/mediaRequestManager.ts +337 -63
  329. package/src/multistream/receiveSlot.ts +68 -26
  330. package/src/multistream/receiveSlotManager.ts +61 -38
  331. package/src/multistream/remoteMedia.ts +29 -3
  332. package/src/multistream/remoteMediaGroup.ts +61 -2
  333. package/src/multistream/remoteMediaManager.ts +260 -66
  334. package/src/networkQualityMonitor/index.ts +6 -6
  335. package/src/reachability/index.ts +75 -25
  336. package/src/reachability/request.ts +10 -5
  337. package/src/reactions/constants.ts +4 -0
  338. package/src/reactions/reactions.ts +4 -4
  339. package/src/reactions/reactions.type.ts +28 -3
  340. package/src/reconnection-manager/index.ts +83 -49
  341. package/src/recording-controller/enums.ts +8 -0
  342. package/src/recording-controller/index.ts +333 -0
  343. package/src/recording-controller/util.ts +75 -0
  344. package/src/roap/index.ts +21 -30
  345. package/src/roap/request.ts +72 -61
  346. package/src/roap/turnDiscovery.ts +51 -27
  347. package/src/statsAnalyzer/global.ts +1 -94
  348. package/src/statsAnalyzer/index.ts +380 -390
  349. package/src/statsAnalyzer/mqaUtil.ts +106 -99
  350. package/test/integration/spec/converged-space-meetings.js +233 -0
  351. package/test/integration/spec/journey.js +336 -259
  352. package/test/integration/spec/space-meeting.js +77 -4
  353. package/test/unit/spec/annotation/index.ts +436 -0
  354. package/test/unit/spec/breakouts/breakout.ts +237 -0
  355. package/test/unit/spec/breakouts/collection.ts +15 -0
  356. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  357. package/test/unit/spec/breakouts/events.ts +89 -0
  358. package/test/unit/spec/breakouts/index.ts +1790 -0
  359. package/test/unit/spec/breakouts/request.ts +104 -0
  360. package/test/unit/spec/breakouts/utils.js +72 -0
  361. package/test/unit/spec/controls-options-manager/index.js +287 -0
  362. package/test/unit/spec/controls-options-manager/util.js +518 -0
  363. package/test/unit/spec/fixture/locus.js +1 -0
  364. package/test/unit/spec/interpretation/collection.ts +15 -0
  365. package/test/unit/spec/interpretation/index.ts +329 -0
  366. package/test/unit/spec/interpretation/siLanguage.ts +26 -0
  367. package/test/unit/spec/locus-info/controlsUtils.js +323 -30
  368. package/test/unit/spec/locus-info/index.js +792 -4
  369. package/test/unit/spec/locus-info/mediaSharesUtils.ts +22 -0
  370. package/test/unit/spec/locus-info/selfConstant.js +48 -0
  371. package/test/unit/spec/locus-info/selfUtils.js +275 -0
  372. package/test/unit/spec/media/index.ts +130 -24
  373. package/test/unit/spec/media/properties.ts +9 -9
  374. package/test/unit/spec/meeting/in-meeting-actions.ts +75 -3
  375. package/test/unit/spec/meeting/index.js +2834 -1442
  376. package/test/unit/spec/meeting/locusMediaRequest.ts +436 -0
  377. package/test/unit/spec/meeting/muteState.js +370 -208
  378. package/test/unit/spec/meeting/request.js +354 -42
  379. package/test/unit/spec/meeting/utils.js +384 -170
  380. package/test/unit/spec/meeting-info/index.js +181 -0
  381. package/test/unit/spec/meeting-info/meetinginfov2.js +383 -5
  382. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  383. package/test/unit/spec/meetings/collection.js +14 -0
  384. package/test/unit/spec/meetings/index.js +847 -121
  385. package/test/unit/spec/meetings/utils.js +206 -2
  386. package/test/unit/spec/member/index.js +31 -0
  387. package/test/unit/spec/member/util.js +408 -32
  388. package/test/unit/spec/members/index.js +320 -1
  389. package/test/unit/spec/members/request.js +206 -27
  390. package/test/unit/spec/members/utils.js +184 -0
  391. package/test/unit/spec/metrics/index.js +1 -50
  392. package/test/unit/spec/multistream/mediaRequestManager.ts +1012 -109
  393. package/test/unit/spec/multistream/receiveSlot.ts +77 -18
  394. package/test/unit/spec/multistream/receiveSlotManager.ts +69 -39
  395. package/test/unit/spec/multistream/remoteMedia.ts +32 -2
  396. package/test/unit/spec/multistream/remoteMediaGroup.ts +271 -5
  397. package/test/unit/spec/multistream/remoteMediaManager.ts +672 -65
  398. package/test/unit/spec/networkQualityMonitor/index.js +4 -4
  399. package/test/unit/spec/reachability/index.ts +176 -25
  400. package/test/unit/spec/reachability/request.js +66 -0
  401. package/test/unit/spec/reconnection-manager/index.js +95 -13
  402. package/test/unit/spec/recording-controller/index.js +307 -0
  403. package/test/unit/spec/recording-controller/util.js +229 -0
  404. package/test/unit/spec/roap/index.ts +28 -52
  405. package/test/unit/spec/roap/request.ts +225 -0
  406. package/test/unit/spec/roap/turnDiscovery.ts +73 -34
  407. package/test/unit/spec/stats-analyzer/index.js +94 -43
  408. package/test/utils/constants.js +9 -0
  409. package/test/utils/integrationTestUtils.js +46 -0
  410. package/test/utils/testUtils.js +0 -45
  411. package/test/utils/webex-config.js +4 -0
  412. package/test/utils/webex-test-users.js +7 -3
  413. package/tsconfig.json +6 -0
  414. package/dist/media/internal-media-core-wrapper.js +0 -18
  415. package/dist/media/internal-media-core-wrapper.js.map +0 -1
  416. package/dist/meeting/effectsState.js +0 -262
  417. package/dist/meeting/effectsState.js.map +0 -1
  418. package/dist/metrics/config.js +0 -299
  419. package/dist/metrics/config.js.map +0 -1
  420. package/dist/multistream/multistreamMedia.js +0 -106
  421. package/dist/multistream/multistreamMedia.js.map +0 -1
  422. package/src/index.js +0 -15
  423. package/src/media/internal-media-core-wrapper.ts +0 -9
  424. package/src/meeting/effectsState.ts +0 -211
  425. package/src/metrics/config.ts +0 -495
  426. package/src/multistream/multistreamMedia.ts +0 -93
  427. package/test/unit/spec/meeting/effectsState.js +0 -281
@@ -0,0 +1,225 @@
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 RoapRequest from '@webex/plugin-meetings/src/roap/request';
6
+ import {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
+ },
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
+ 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
+ );
55
+
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: 'test',
69
+ },
70
+ })
71
+ );
72
+ });
73
+
74
+ describe('#attachReachabilityData', () => {
75
+ it('returns the correct reachability data', async () => {
76
+ const res = await roapRequest.attachReachabilityData({});
77
+
78
+ assert.deepEqual(res.localSdp, {
79
+ reachability: {
80
+ clusterId: {
81
+ udp: 'test',
82
+ },
83
+ },
84
+ });
85
+ assert.deepEqual(res.joinCookie, {
86
+ anycastEntryPoint: 'aws-eu-west-1',
87
+ });
88
+ });
89
+
90
+ it('handles the case when reachability data does not exist', async () => {
91
+ await webex.boundedStorage.del(REACHABILITY.namespace, REACHABILITY.localStorageJoinCookie);
92
+
93
+ await webex.boundedStorage.del(REACHABILITY.namespace, REACHABILITY.localStorageResult);
94
+ const sdp = {
95
+ some: 'attribute',
96
+ };
97
+
98
+ const result = await roapRequest.attachReachabilityData(sdp);
99
+
100
+ assert.deepEqual(result, {
101
+ joinCookie: undefined,
102
+ localSdp: {
103
+ some: 'attribute',
104
+ },
105
+ });
106
+ });
107
+ });
108
+
109
+ describe('sendRoap', () => {
110
+ it('includes joinCookie in the request correctly', async () => {
111
+ const locusMediaRequest = {send: sinon.stub().resolves({body: {locus: {}}})};
112
+
113
+ await roapRequest.sendRoap({
114
+ locusSelfUrl: locusUrl,
115
+ mediaId: 'mediaId',
116
+ roapMessage: {
117
+ seq: 'seq',
118
+ },
119
+ meetingId: 'meeting-id',
120
+ locusMediaRequest,
121
+ });
122
+
123
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
124
+ name: 'client.locus.media.request',
125
+ options: {
126
+ meetingId: 'meeting-id',
127
+ },
128
+ });
129
+
130
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
131
+ name: 'client.locus.media.response',
132
+ options: {
133
+ meetingId: 'meeting-id',
134
+ },
135
+ });
136
+
137
+ const requestParams = locusMediaRequest.send.getCall(0).args[0];
138
+ assert.deepEqual(requestParams, {
139
+ type: 'RoapMessage',
140
+ selfUrl: locusUrl,
141
+ joinCookie: {
142
+ anycastEntryPoint: 'aws-eu-west-1',
143
+ },
144
+ mediaId: 'mediaId',
145
+ roapMessage: {
146
+ seq: 'seq',
147
+ },
148
+ reachability: {clusterId: {udp: 'test'}},
149
+ });
150
+ });
151
+
152
+ it('sends correct client event when fails', async () => {
153
+ const locusMediaRequest = {send: sinon.stub().rejects({code: 300, message: 'error'})};
154
+ try {
155
+ await roapRequest.sendRoap({
156
+ locusSelfUrl: locusUrl,
157
+ mediaId: 'mediaId',
158
+ roapMessage: {
159
+ seq: 'seq',
160
+ },
161
+ meetingId: 'meeting-id',
162
+ locusMediaRequest,
163
+ });
164
+ } catch (err) {
165
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
166
+ name: 'client.locus.media.response',
167
+ options: {
168
+ meetingId: 'meeting-id',
169
+ rawError: {code: 300, message: 'error'},
170
+ },
171
+ });
172
+ }
173
+ });
174
+ });
175
+
176
+ it('calls attachReachabilityData when sendRoap', async () => {
177
+ const locusMediaRequest = { send: sinon.stub().resolves({body: {locus: {}}})};
178
+
179
+ const newSdp = {
180
+ new: 'sdp',
181
+ reachability: { someResult: 'whatever' }
182
+ };
183
+
184
+ roapRequest.attachReachabilityData = sinon.stub().returns(
185
+ Promise.resolve({
186
+ localSdp: newSdp,
187
+ joinCookie: {
188
+ anycastEntryPoint: 'aws-eu-west-1',
189
+ },
190
+ })
191
+ );
192
+
193
+ await roapRequest.sendRoap({
194
+ roapMessage: {
195
+ seq: 1,
196
+ },
197
+ locusSelfUrl: 'locusSelfUrl',
198
+ mediaId: 'mediaId',
199
+ meetingId: 'meetingId',
200
+ preferTranscoding: true,
201
+ locusMediaRequest
202
+ });
203
+
204
+ const requestParams = locusMediaRequest.send.getCall(0).args[0];
205
+
206
+ assert.deepEqual(requestParams, {
207
+ type: 'RoapMessage',
208
+ selfUrl: 'locusSelfUrl',
209
+ joinCookie: {
210
+ anycastEntryPoint: 'aws-eu-west-1',
211
+ },
212
+ mediaId: 'mediaId',
213
+ roapMessage: {
214
+ seq: 1,
215
+ },
216
+ reachability: { someResult: 'whatever' },
217
+ });
218
+
219
+ assert.calledOnceWithExactly(roapRequest.attachReachabilityData, {
220
+ roapMessage: {
221
+ seq: 1,
222
+ },
223
+ });
224
+ });
225
+ });
@@ -40,13 +40,19 @@ describe('TurnDiscovery', () => {
40
40
  mediaId: 'fake media id',
41
41
  locusUrl: `https://locus-a.wbx2.com/locus/api/v1/loci/${FAKE_LOCUS_ID}`,
42
42
  roapSeq: -1,
43
- isAudioMuted: () => true,
44
- isVideoMuted: () => false,
43
+ audio:{
44
+ isLocallyMuted: () => true,
45
+ },
46
+ video:{
47
+ isLocallyMuted: () => false,
48
+ },
45
49
  setRoapSeq: sinon.fake((newSeq) => {
46
50
  testMeeting.roapSeq = newSeq;
47
51
  }),
48
52
  updateMediaConnections: sinon.stub(),
49
- webex: {meetings: {reachability: {isAnyClusterReachable: () => false}}},
53
+ webex: {meetings: {reachability: {isAnyClusterReachable: () => Promise.resolve(false)}}},
54
+ isMultistream: false,
55
+ locusMediaRequest: { fake: true },
50
56
  };
51
57
  });
52
58
 
@@ -69,12 +75,10 @@ describe('TurnDiscovery', () => {
69
75
  version: '2',
70
76
  seq: expectedSeq,
71
77
  },
72
- correlationId: testMeeting.correlationId,
73
78
  locusSelfUrl: testMeeting.selfUrl,
74
79
  mediaId: expectedMediaId,
75
- audioMuted: testMeeting.isAudioMuted(),
76
- videoMuted: testMeeting.isVideoMuted(),
77
80
  meetingId: testMeeting.id,
81
+ locusMediaRequest: testMeeting.locusMediaRequest
78
82
  });
79
83
 
80
84
  if (messageType === 'TURN_DISCOVERY_REQUEST') {
@@ -97,39 +101,44 @@ describe('TurnDiscovery', () => {
97
101
  };
98
102
 
99
103
  describe('doTurnDiscovery', () => {
100
- it('sends TURN_DISCOVERY_REQUEST, waits for response and sends OK', async () => {
101
- const td = new TurnDiscovery(mockRoapRequest);
104
+ [false, true].forEach(function (enabledMultistream ) {
105
+ it('sends TURN_DISCOVERY_REQUEST'+ (enabledMultistream ? ' when enable Multistream':'') + ', waits for response and sends OK', async () => {
106
+ testMeeting.isMultistream = enabledMultistream;
102
107
 
103
- const result = td.doTurnDiscovery(testMeeting, false);
108
+ const td = new TurnDiscovery(mockRoapRequest);
104
109
 
105
- // check that TURN_DISCOVERY_REQUEST was sent
106
- await checkRoapMessageSent('TURN_DISCOVERY_REQUEST', 0);
110
+ const result = td.doTurnDiscovery(testMeeting, false);
107
111
 
108
- mockRoapRequest.sendRoap.resetHistory();
112
+ // check that TURN_DISCOVERY_REQUEST was sent
113
+ await checkRoapMessageSent('TURN_DISCOVERY_REQUEST', 0);
109
114
 
110
- // simulate the response
111
- td.handleTurnDiscoveryResponse({
112
- headers: [
113
- `x-cisco-turn-url=${FAKE_TURN_URL}`,
114
- `x-cisco-turn-username=${FAKE_TURN_USERNAME}`,
115
- `x-cisco-turn-password=${FAKE_TURN_PASSWORD}`,
116
- ],
117
- });
115
+ // @ts-ignore
116
+ mockRoapRequest.sendRoap.resetHistory();
118
117
 
119
- await testUtils.flushPromises();
118
+ // simulate the response
119
+ td.handleTurnDiscoveryResponse({
120
+ headers: [
121
+ `x-cisco-turn-url=${FAKE_TURN_URL}`,
122
+ `x-cisco-turn-username=${FAKE_TURN_USERNAME}`,
123
+ `x-cisco-turn-password=${FAKE_TURN_PASSWORD}`,
124
+ ]
125
+ });
120
126
 
121
- // check that we've sent OK
122
- await checkRoapMessageSent('OK', 0);
127
+ await testUtils.flushPromises();
123
128
 
124
- const {turnServerInfo, turnDiscoverySkippedReason} = await result;
129
+ // check that we've sent OK
130
+ await checkRoapMessageSent('OK', 0);
125
131
 
126
- assert.deepEqual(turnServerInfo, {
127
- url: FAKE_TURN_URL,
128
- username: FAKE_TURN_USERNAME,
129
- password: FAKE_TURN_PASSWORD,
130
- });
132
+ const {turnServerInfo, turnDiscoverySkippedReason} = await result;
131
133
 
132
- assert.isUndefined(turnDiscoverySkippedReason);
134
+ assert.deepEqual(turnServerInfo, {
135
+ url: FAKE_TURN_URL,
136
+ username: FAKE_TURN_USERNAME,
137
+ password: FAKE_TURN_PASSWORD
138
+ });
139
+
140
+ assert.isUndefined(turnDiscoverySkippedReason);
141
+ });
133
142
  });
134
143
 
135
144
  it('sends TURN_DISCOVERY_REQUEST with empty mediaId when isReconnecting is true', async () => {
@@ -141,6 +150,7 @@ describe('TurnDiscovery', () => {
141
150
  await checkRoapMessageSent('TURN_DISCOVERY_REQUEST', 0, '');
142
151
 
143
152
  // the main part of the test is complete now, checking the remaining part of the flow just for completeness
153
+ // @ts-ignore
144
154
  mockRoapRequest.sendRoap.resetHistory();
145
155
 
146
156
  // simulate the response
@@ -173,7 +183,7 @@ describe('TurnDiscovery', () => {
173
183
 
174
184
  // check that TURN_DISCOVERY_REQUEST was sent
175
185
  await checkRoapMessageSent('TURN_DISCOVERY_REQUEST', 0);
176
-
186
+ // @ts-ignore
177
187
  mockRoapRequest.sendRoap.resetHistory();
178
188
 
179
189
  // simulate the response with some extra headers
@@ -206,7 +216,7 @@ describe('TurnDiscovery', () => {
206
216
  const prevConfigValue = testMeeting.config.experimental.enableTurnDiscovery;
207
217
 
208
218
  testMeeting.config.experimental.enableTurnDiscovery = false;
209
-
219
+ // @ts-ignore
210
220
  const result = await new TurnDiscovery(mockRoapRequest).doTurnDiscovery(testMeeting);
211
221
 
212
222
  const {turnServerInfo, turnDiscoverySkippedReason} = result;
@@ -236,7 +246,7 @@ describe('TurnDiscovery', () => {
236
246
 
237
247
  it('resolves with undefined when cluster is reachable', async () => {
238
248
  const prev = testMeeting.webex.meetings.reachability.isAnyClusterReachable;
239
- testMeeting.webex.meetings.reachability.isAnyClusterReachable = () => true;
249
+ testMeeting.webex.meetings.reachability.isAnyClusterReachable = () => Promise.resolve(true);
240
250
  const result = await new TurnDiscovery(mockRoapRequest).doTurnDiscovery(testMeeting);
241
251
 
242
252
  const {turnServerInfo, turnDiscoverySkippedReason} = result;
@@ -267,6 +277,8 @@ describe('TurnDiscovery', () => {
267
277
  const td = new TurnDiscovery(mockRoapRequest);
268
278
  const turnDiscoveryPromise = td.doTurnDiscovery(testMeeting, false);
269
279
 
280
+ await testUtils.flushPromises();
281
+
270
282
  // simulate the response without the password
271
283
  td.handleTurnDiscoveryResponse({
272
284
  headers: [
@@ -286,6 +298,8 @@ describe('TurnDiscovery', () => {
286
298
  const td = new TurnDiscovery(mockRoapRequest);
287
299
  const turnDiscoveryPromise = td.doTurnDiscovery(testMeeting, false);
288
300
 
301
+ await testUtils.flushPromises();
302
+
289
303
  // simulate the response without the headers
290
304
  td.handleTurnDiscoveryResponse({});
291
305
 
@@ -301,6 +315,8 @@ describe('TurnDiscovery', () => {
301
315
  const td = new TurnDiscovery(mockRoapRequest);
302
316
  const turnDiscoveryPromise = td.doTurnDiscovery(testMeeting, false);
303
317
 
318
+ await testUtils.flushPromises();
319
+
304
320
  // simulate the response without the headers
305
321
  td.handleTurnDiscoveryResponse({headers: []});
306
322
 
@@ -317,9 +333,11 @@ describe('TurnDiscovery', () => {
317
333
 
318
334
  const turnDiscoveryPromise = td.doTurnDiscovery(testMeeting, false);
319
335
 
336
+ await testUtils.flushPromises();
337
+
320
338
  // check that TURN_DISCOVERY_REQUEST was sent
321
339
  await checkRoapMessageSent('TURN_DISCOVERY_REQUEST', 0);
322
-
340
+ // @ts-ignore
323
341
  mockRoapRequest.sendRoap.resetHistory();
324
342
 
325
343
  // setup the mock so that sending of OK fails
@@ -347,6 +365,27 @@ describe('TurnDiscovery', () => {
347
365
  });
348
366
  });
349
367
 
368
+ describe('isSkipped', () => {
369
+ [
370
+ {enabledInConfig: true, isAnyClusterReachable: true, expectedIsSkipped: true},
371
+ {enabledInConfig: true, isAnyClusterReachable: false, expectedIsSkipped: false},
372
+ {enabledInConfig: false, isAnyClusterReachable: true, expectedIsSkipped: true},
373
+ {enabledInConfig: false, isAnyClusterReachable: false, expectedIsSkipped: true},
374
+ ].forEach(({enabledInConfig, isAnyClusterReachable, expectedIsSkipped}) => {
375
+ it(`returns ${expectedIsSkipped} when TURN discovery is ${enabledInConfig ? '' : 'not '} enabled in config and isAnyClusterReachable() returns ${isAnyClusterReachable ? 'true' : 'false'}`, async () => {
376
+ testMeeting.config.experimental.enableTurnDiscovery = enabledInConfig;
377
+
378
+ sinon.stub(testMeeting.webex.meetings.reachability, 'isAnyClusterReachable').resolves(isAnyClusterReachable);
379
+
380
+ const td = new TurnDiscovery(mockRoapRequest);
381
+
382
+ const isSkipped = await td.isSkipped(testMeeting);
383
+
384
+ assert.equal(isSkipped, expectedIsSkipped);
385
+ })
386
+ })
387
+ })
388
+
350
389
  describe('handleTurnDiscoveryResponse', () => {
351
390
  it("doesn't do anything if turn discovery was not started", () => {
352
391
  const td = new TurnDiscovery(mockRoapRequest);
@@ -2,7 +2,7 @@ import 'jsdom-global/register';
2
2
  import chai from 'chai';
3
3
  import chaiAsPromised from 'chai-as-promised';
4
4
  import sinon from 'sinon';
5
- import {MediaConnection as MC} from '@webex/internal-media-core';
5
+ import {ConnectionState} from '@webex/internal-media-core';
6
6
 
7
7
  import {StatsAnalyzer, EVENTS} from '../../../../src/statsAnalyzer';
8
8
  import NetworkQualityMonitor from '../../../../src/networkQualityMonitor';
@@ -24,14 +24,15 @@ describe('plugin-meetings', () => {
24
24
  };
25
25
 
26
26
  const defaultStats = {
27
+ resolutions: {},
27
28
  internal: {
28
- video: {
29
+ 'video-send-1': {
29
30
  send: {
30
31
  totalPacketsLostOnReceiver: 10,
31
32
  },
32
33
  },
33
34
  },
34
- video: {
35
+ 'video-send-1': {
35
36
  send: {
36
37
  packetsSent: 2,
37
38
  meanRemoteJitter: [],
@@ -52,7 +53,12 @@ describe('plugin-meetings', () => {
52
53
  beforeEach(() => {
53
54
  const networkQualityMonitor = new NetworkQualityMonitor(initialConfig);
54
55
 
55
- statsAnalyzer = new StatsAnalyzer(initialConfig, networkQualityMonitor, defaultStats);
56
+ statsAnalyzer = new StatsAnalyzer(
57
+ initialConfig,
58
+ () => ({}),
59
+ networkQualityMonitor,
60
+ defaultStats
61
+ );
56
62
 
57
63
  sandBoxSpy = sandbox.spy(
58
64
  statsAnalyzer.networkQualityMonitor,
@@ -65,12 +71,12 @@ describe('plugin-meetings', () => {
65
71
  });
66
72
 
67
73
  it('should trigger determineUplinkNetworkQuality with specific arguments', async () => {
68
- await statsAnalyzer.parseGetStatsResult(statusResult, 'video');
74
+ await statsAnalyzer.parseGetStatsResult(statusResult, 'video-send-1', true);
69
75
 
70
76
  assert.calledOnce(statsAnalyzer.networkQualityMonitor.determineUplinkNetworkQuality);
71
77
  assert(
72
78
  sandBoxSpy.calledWith({
73
- mediaType: 'video',
79
+ mediaType: 'video-send-1',
74
80
  remoteRtpResults: statusResult,
75
81
  statsAnalyzerCurrentStats: statsAnalyzer.statsResults,
76
82
  })
@@ -83,6 +89,7 @@ describe('plugin-meetings', () => {
83
89
  let pc;
84
90
  let networkQualityMonitor;
85
91
  let statsAnalyzer;
92
+ let mqeData;
86
93
 
87
94
  let receivedEventsData = {
88
95
  local: {},
@@ -110,57 +117,83 @@ describe('plugin-meetings', () => {
110
117
  // bytesReceived and bytesSent need to be non-zero in order for StatsAnalyzer to parse any other values
111
118
  fakeStats = {
112
119
  audio: {
113
- receiver: {
114
- type: 'inbound-rtp',
115
- packetsReceived: 0,
116
- bytesReceived: 1,
117
- },
118
- sender: {
119
- type: 'outbound-rtp',
120
- packetsSent: 0,
121
- bytesSent: 1,
122
- },
120
+ senders: [
121
+ {
122
+ report: [
123
+ {
124
+ type: 'outbound-rtp',
125
+ packetsSent: 0,
126
+ bytesSent: 1,
127
+ },
128
+ ],
129
+ },
130
+ ],
131
+ receivers: [
132
+ {
133
+ report: [
134
+ {
135
+ type: 'inbound-rtp',
136
+ packetsReceived: 0,
137
+ bytesReceived: 1,
138
+ },
139
+ ],
140
+ },
141
+ ],
123
142
  },
124
143
  video: {
125
- receiver: {
126
- type: 'inbound-rtp',
127
- framesDecoded: 0,
128
- bytesReceived: 1,
129
- },
130
- sender: {
131
- type: 'outbound-rtp',
132
- framesSent: 0,
133
- bytesSent: 1,
134
- },
144
+ senders: [
145
+ {
146
+ report: [
147
+ {
148
+ type: 'outbound-rtp',
149
+ framesSent: 0,
150
+ bytesSent: 1,
151
+ },
152
+ ],
153
+ },
154
+ ],
155
+ receivers: [
156
+ {
157
+ report: [
158
+ {
159
+ type: 'inbound-rtp',
160
+ framesDecoded: 0,
161
+ bytesReceived: 1,
162
+ frameHeight: 720,
163
+ frameWidth: 1280,
164
+ framesReceived: 1,
165
+ },
166
+ ],
167
+ },
168
+ ],
135
169
  },
136
170
  };
137
171
 
138
172
  pc = {
139
- getConnectionState: sinon.stub().returns(MC.ConnectionState.Connected),
173
+ getConnectionState: sinon.stub().returns(ConnectionState.Connected),
140
174
  getTransceiverStats: sinon.stub().resolves({
141
175
  audio: {
142
- sender: [fakeStats.audio.sender],
143
- receiver: [fakeStats.audio.receiver],
144
- currentDirection: 'sendrecv',
145
- localTrackLabel: 'fake mic',
176
+ senders: [fakeStats.audio.senders[0]],
177
+ receivers: [fakeStats.audio.receivers[0]],
146
178
  },
147
179
  video: {
148
- sender: [fakeStats.video.sender],
149
- receiver: [fakeStats.video.receiver],
150
- currentDirection: 'sendrecv',
151
- localTrackLabel: 'fake camera',
180
+ senders: [fakeStats.video.senders[0]],
181
+ receivers: [fakeStats.video.receivers[0]],
182
+ },
183
+ screenShareAudio: {
184
+ senders: [],
185
+ receivers: [],
152
186
  },
153
187
  screenShareVideo: {
154
- sender: [],
155
- receiver: [],
156
- currentDirection: 'sendrecv',
188
+ senders: [],
189
+ receivers: [],
157
190
  },
158
191
  }),
159
192
  };
160
193
 
161
194
  networkQualityMonitor = new NetworkQualityMonitor(initialConfig);
162
195
 
163
- statsAnalyzer = new StatsAnalyzer(initialConfig, networkQualityMonitor);
196
+ statsAnalyzer = new StatsAnalyzer(initialConfig, () => ({}), networkQualityMonitor);
164
197
 
165
198
  statsAnalyzer.on(EVENTS.LOCAL_MEDIA_STARTED, (data) => {
166
199
  receivedEventsData.local.started = data;
@@ -174,6 +207,9 @@ describe('plugin-meetings', () => {
174
207
  statsAnalyzer.on(EVENTS.REMOTE_MEDIA_STOPPED, (data) => {
175
208
  receivedEventsData.remote.stopped = data;
176
209
  });
210
+ statsAnalyzer.on(EVENTS.MEDIA_QUALITY, ({data}) => {
211
+ mqeData = data;
212
+ });
177
213
  });
178
214
 
179
215
  afterEach(() => {
@@ -200,6 +236,12 @@ describe('plugin-meetings', () => {
200
236
  assert.deepEqual(receivedEventsData.remote.stopped, expected.remote?.stopped);
201
237
  };
202
238
 
239
+ const checkMqeData = () => {
240
+ assert.strictEqual(mqeData.videoReceive[0].streams[0].receivedFrameSize, 3600);
241
+ assert.strictEqual(mqeData.videoReceive[0].streams[0].receivedHeight, 720);
242
+ assert.strictEqual(mqeData.videoReceive[0].streams[0].receivedWidth, 1280);
243
+ };
244
+
203
245
  it('emits LOCAL_MEDIA_STARTED and LOCAL_MEDIA_STOPPED events for audio', async () => {
204
246
  await startStatsAnalyzer({expected: {sendAudio: true}});
205
247
 
@@ -207,7 +249,7 @@ describe('plugin-meetings', () => {
207
249
  checkReceivedEvent({expected: {}});
208
250
 
209
251
  // setup a mock to return some values higher the previous ones
210
- fakeStats.audio.sender.packetsSent += 10;
252
+ fakeStats.audio.senders[0].report[0].packetsSent += 10;
211
253
 
212
254
  await progressTime();
213
255
 
@@ -227,7 +269,7 @@ describe('plugin-meetings', () => {
227
269
  checkReceivedEvent({expected: {}});
228
270
 
229
271
  // setup a mock to return some values higher the previous ones
230
- fakeStats.video.sender.framesSent += 1;
272
+ fakeStats.video.senders[0].report[0].framesSent += 1;
231
273
 
232
274
  await progressTime();
233
275
 
@@ -247,7 +289,7 @@ describe('plugin-meetings', () => {
247
289
  checkReceivedEvent({expected: {}});
248
290
 
249
291
  // setup a mock to return some values higher the previous ones
250
- fakeStats.audio.receiver.packetsReceived += 5;
292
+ fakeStats.audio.receivers[0].report[0].packetsReceived += 5;
251
293
 
252
294
  await progressTime();
253
295
  // check that we got the REMOTE_MEDIA_STARTED event for audio
@@ -267,7 +309,7 @@ describe('plugin-meetings', () => {
267
309
  checkReceivedEvent({expected: {}});
268
310
 
269
311
  // setup a mock to return some values higher the previous ones
270
- fakeStats.video.receiver.framesDecoded += 1;
312
+ fakeStats.video.receivers[0].report[0].framesDecoded += 1;
271
313
 
272
314
  await progressTime();
273
315
  // check that we got the REMOTE_MEDIA_STARTED event for video
@@ -279,6 +321,15 @@ describe('plugin-meetings', () => {
279
321
 
280
322
  checkReceivedEvent({expected: {remote: {stopped: {type: 'video'}}}});
281
323
  });
324
+
325
+ it('emits the correct MEDIA_QUALITY events', async () => {
326
+ await startStatsAnalyzer({expected: {receiveVideo: true}});
327
+
328
+ await progressTime();
329
+
330
+ // Check that the mqe data has been emitted and is correctly computed.
331
+ checkMqeData();
332
+ });
282
333
  });
283
334
  });
284
335
  });
@@ -0,0 +1,9 @@
1
+ // MOVE TO TEST CONSTANTS
2
+ export const MEDIA_SERVERS = {
3
+ // The homer media server for converged multistream meetings.
4
+ HOMER: 'homer',
5
+ // The linus media server
6
+ LINUS: 'linus',
7
+ // The calliope media server for transcoded meetings
8
+ CALLIOPE: 'calliope',
9
+ };