@webex/plugin-meetings 3.0.0-beta.21 → 3.0.0-beta.211

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 (422) 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 +342 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +114 -14
  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 +841 -19
  15. package/dist/breakouts/index.js.map +1 -1
  16. package/dist/breakouts/request.js +78 -0
  17. package/dist/breakouts/request.js.map +1 -0
  18. package/dist/breakouts/utils.js +67 -0
  19. package/dist/breakouts/utils.js.map +1 -0
  20. package/dist/common/errors/webex-errors.js +3 -2
  21. package/dist/common/errors/webex-errors.js.map +1 -1
  22. package/dist/common/logs/logger-proxy.js +1 -1
  23. package/dist/common/logs/logger-proxy.js.map +1 -1
  24. package/dist/common/queue.js +24 -9
  25. package/dist/common/queue.js.map +1 -1
  26. package/dist/config.js +3 -8
  27. package/dist/config.js.map +1 -1
  28. package/dist/constants.js +179 -30
  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 +319 -0
  39. package/dist/controls-options-manager/util.js.map +1 -0
  40. package/dist/index.js +106 -1
  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 +366 -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 +91 -2
  49. package/dist/locus-info/controlsUtils.js.map +1 -1
  50. package/dist/locus-info/index.js +359 -64
  51. package/dist/locus-info/index.js.map +1 -1
  52. package/dist/locus-info/infoUtils.js +7 -1
  53. package/dist/locus-info/infoUtils.js.map +1 -1
  54. package/dist/locus-info/mediaSharesUtils.js +43 -1
  55. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  56. package/dist/locus-info/parser.js +219 -63
  57. package/dist/locus-info/parser.js.map +1 -1
  58. package/dist/locus-info/selfUtils.js +89 -14
  59. package/dist/locus-info/selfUtils.js.map +1 -1
  60. package/dist/media/index.js +48 -135
  61. package/dist/media/index.js.map +1 -1
  62. package/dist/media/properties.js +29 -90
  63. package/dist/media/properties.js.map +1 -1
  64. package/dist/mediaQualityMetrics/config.js +505 -493
  65. package/dist/mediaQualityMetrics/config.js.map +1 -1
  66. package/dist/meeting/in-meeting-actions.js +90 -2
  67. package/dist/meeting/in-meeting-actions.js.map +1 -1
  68. package/dist/meeting/index.js +2770 -2547
  69. package/dist/meeting/index.js.map +1 -1
  70. package/dist/meeting/locusMediaRequest.js +291 -0
  71. package/dist/meeting/locusMediaRequest.js.map +1 -0
  72. package/dist/meeting/muteState.js +229 -124
  73. package/dist/meeting/muteState.js.map +1 -1
  74. package/dist/meeting/request.js +199 -193
  75. package/dist/meeting/request.js.map +1 -1
  76. package/dist/meeting/util.js +532 -414
  77. package/dist/meeting/util.js.map +1 -1
  78. package/dist/meeting-info/index.js +48 -7
  79. package/dist/meeting-info/index.js.map +1 -1
  80. package/dist/meeting-info/meeting-info-v2.js +171 -51
  81. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  82. package/dist/meeting-info/utilv2.js +20 -5
  83. package/dist/meeting-info/utilv2.js.map +1 -1
  84. package/dist/meetings/collection.js +22 -0
  85. package/dist/meetings/collection.js.map +1 -1
  86. package/dist/meetings/index.js +357 -66
  87. package/dist/meetings/index.js.map +1 -1
  88. package/dist/meetings/meetings.types.js +7 -0
  89. package/dist/meetings/meetings.types.js.map +1 -0
  90. package/dist/meetings/request.js +2 -0
  91. package/dist/meetings/request.js.map +1 -1
  92. package/dist/meetings/util.js +88 -1
  93. package/dist/meetings/util.js.map +1 -1
  94. package/dist/member/index.js +49 -0
  95. package/dist/member/index.js.map +1 -1
  96. package/dist/member/types.js +25 -0
  97. package/dist/member/types.js.map +1 -0
  98. package/dist/member/util.js +121 -25
  99. package/dist/member/util.js.map +1 -1
  100. package/dist/members/collection.js +10 -0
  101. package/dist/members/collection.js.map +1 -1
  102. package/dist/members/index.js +86 -5
  103. package/dist/members/index.js.map +1 -1
  104. package/dist/members/request.js +106 -38
  105. package/dist/members/request.js.map +1 -1
  106. package/dist/members/types.js +15 -0
  107. package/dist/members/types.js.map +1 -0
  108. package/dist/members/util.js +316 -233
  109. package/dist/members/util.js.map +1 -1
  110. package/dist/metrics/constants.js +3 -5
  111. package/dist/metrics/constants.js.map +1 -1
  112. package/dist/metrics/index.js +1 -468
  113. package/dist/metrics/index.js.map +1 -1
  114. package/dist/multistream/mediaRequestManager.js +238 -49
  115. package/dist/multistream/mediaRequestManager.js.map +1 -1
  116. package/dist/multistream/receiveSlot.js +49 -16
  117. package/dist/multistream/receiveSlot.js.map +1 -1
  118. package/dist/multistream/receiveSlotManager.js +52 -34
  119. package/dist/multistream/receiveSlotManager.js.map +1 -1
  120. package/dist/multistream/remoteMedia.js +44 -18
  121. package/dist/multistream/remoteMedia.js.map +1 -1
  122. package/dist/multistream/remoteMediaGroup.js +60 -3
  123. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  124. package/dist/multistream/remoteMediaManager.js +173 -59
  125. package/dist/multistream/remoteMediaManager.js.map +1 -1
  126. package/dist/networkQualityMonitor/index.js +4 -2
  127. package/dist/networkQualityMonitor/index.js.map +1 -1
  128. package/dist/reachability/index.js +72 -27
  129. package/dist/reachability/index.js.map +1 -1
  130. package/dist/reachability/request.js +12 -5
  131. package/dist/reachability/request.js.map +1 -1
  132. package/dist/reconnection-manager/index.js +196 -155
  133. package/dist/reconnection-manager/index.js.map +1 -1
  134. package/dist/recording-controller/index.js +21 -2
  135. package/dist/recording-controller/index.js.map +1 -1
  136. package/dist/recording-controller/util.js +9 -8
  137. package/dist/recording-controller/util.js.map +1 -1
  138. package/dist/roap/index.js +21 -29
  139. package/dist/roap/index.js.map +1 -1
  140. package/dist/roap/request.js +110 -89
  141. package/dist/roap/request.js.map +1 -1
  142. package/dist/roap/turnDiscovery.js +93 -36
  143. package/dist/roap/turnDiscovery.js.map +1 -1
  144. package/dist/rtcMetrics/constants.js +12 -0
  145. package/dist/rtcMetrics/constants.js.map +1 -0
  146. package/dist/rtcMetrics/index.js +117 -0
  147. package/dist/rtcMetrics/index.js.map +1 -0
  148. package/dist/statsAnalyzer/global.js +1 -93
  149. package/dist/statsAnalyzer/global.js.map +1 -1
  150. package/dist/statsAnalyzer/index.js +326 -311
  151. package/dist/statsAnalyzer/index.js.map +1 -1
  152. package/dist/statsAnalyzer/mqaUtil.js +90 -53
  153. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  154. package/dist/types/annotation/annotation.types.d.ts +42 -0
  155. package/dist/types/annotation/constants.d.ts +31 -0
  156. package/dist/types/annotation/index.d.ts +117 -0
  157. package/dist/types/breakouts/breakout.d.ts +8 -0
  158. package/dist/types/breakouts/collection.d.ts +5 -0
  159. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  160. package/dist/types/breakouts/events.d.ts +8 -0
  161. package/dist/types/breakouts/index.d.ts +5 -0
  162. package/dist/types/breakouts/request.d.ts +22 -0
  163. package/dist/types/breakouts/utils.d.ts +15 -0
  164. package/dist/types/common/browser-detection.d.ts +9 -0
  165. package/dist/types/common/collection.d.ts +48 -0
  166. package/dist/types/common/config.d.ts +2 -0
  167. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  168. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  169. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  170. package/dist/types/common/errors/media.d.ts +15 -0
  171. package/dist/types/common/errors/parameter.d.ts +15 -0
  172. package/dist/types/common/errors/password-error.d.ts +15 -0
  173. package/dist/types/common/errors/permission.d.ts +14 -0
  174. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  175. package/dist/types/common/errors/reconnection.d.ts +15 -0
  176. package/dist/types/common/errors/stats.d.ts +15 -0
  177. package/dist/types/common/errors/webex-errors.d.ts +69 -0
  178. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  179. package/dist/types/common/events/events-scope.d.ts +17 -0
  180. package/dist/types/common/events/events.d.ts +12 -0
  181. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  182. package/dist/types/common/events/util.d.ts +2 -0
  183. package/dist/types/common/logs/logger-config.d.ts +2 -0
  184. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  185. package/dist/types/common/logs/request.d.ts +34 -0
  186. package/dist/types/common/queue.d.ts +34 -0
  187. package/dist/types/config.d.ts +72 -0
  188. package/dist/types/constants.d.ts +1020 -0
  189. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  190. package/dist/types/controls-options-manager/enums.d.ts +15 -0
  191. package/dist/types/controls-options-manager/index.d.ts +136 -0
  192. package/dist/types/controls-options-manager/types.d.ts +43 -0
  193. package/dist/types/controls-options-manager/util.d.ts +1 -0
  194. package/dist/types/index.d.ts +7 -0
  195. package/dist/types/interpretation/collection.d.ts +5 -0
  196. package/dist/types/interpretation/index.d.ts +5 -0
  197. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  198. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  199. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  200. package/dist/types/locus-info/fullState.d.ts +2 -0
  201. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  202. package/dist/types/locus-info/index.d.ts +322 -0
  203. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  204. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  205. package/dist/types/locus-info/parser.d.ts +271 -0
  206. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  207. package/dist/types/media/index.d.ts +34 -0
  208. package/dist/types/media/properties.d.ts +93 -0
  209. package/dist/types/media/util.d.ts +2 -0
  210. package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
  211. package/dist/types/meeting/in-meeting-actions.d.ts +163 -0
  212. package/dist/types/meeting/index.d.ts +1482 -0
  213. package/dist/types/meeting/locusMediaRequest.d.ts +72 -0
  214. package/dist/types/meeting/muteState.d.ts +184 -0
  215. package/dist/types/meeting/request.d.ts +257 -0
  216. package/dist/types/meeting/request.type.d.ts +11 -0
  217. package/dist/types/meeting/state.d.ts +9 -0
  218. package/dist/types/meeting/util.d.ts +79 -0
  219. package/dist/types/meeting-info/collection.d.ts +20 -0
  220. package/dist/types/meeting-info/index.d.ts +62 -0
  221. package/dist/types/meeting-info/meeting-info-v2.d.ts +122 -0
  222. package/dist/types/meeting-info/request.d.ts +22 -0
  223. package/dist/types/meeting-info/util.d.ts +2 -0
  224. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  225. package/dist/types/meetings/collection.d.ts +31 -0
  226. package/dist/types/meetings/index.d.ts +367 -0
  227. package/dist/types/meetings/meetings.types.d.ts +4 -0
  228. package/dist/types/meetings/request.d.ts +27 -0
  229. package/dist/types/meetings/util.d.ts +18 -0
  230. package/dist/types/member/index.d.ts +159 -0
  231. package/dist/types/member/types.d.ts +32 -0
  232. package/dist/types/member/util.d.ts +2 -0
  233. package/dist/types/members/collection.d.ts +29 -0
  234. package/dist/types/members/index.d.ts +353 -0
  235. package/dist/types/members/request.d.ts +114 -0
  236. package/dist/types/members/types.d.ts +24 -0
  237. package/dist/types/members/util.d.ts +210 -0
  238. package/dist/types/metrics/constants.d.ts +55 -0
  239. package/dist/types/metrics/index.d.ts +45 -0
  240. package/dist/types/multistream/mediaRequestManager.d.ts +118 -0
  241. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  242. package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
  243. package/dist/types/multistream/remoteMedia.d.ts +72 -0
  244. package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
  245. package/dist/types/multistream/remoteMediaManager.d.ts +277 -0
  246. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  247. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  248. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  249. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  250. package/dist/types/reachability/index.d.ts +152 -0
  251. package/dist/types/reachability/request.d.ts +37 -0
  252. package/dist/types/reactions/constants.d.ts +3 -0
  253. package/dist/types/reactions/reactions.d.ts +4 -0
  254. package/dist/types/reactions/reactions.type.d.ts +52 -0
  255. package/dist/types/reconnection-manager/index.d.ts +126 -0
  256. package/dist/types/recording-controller/enums.d.ts +7 -0
  257. package/dist/types/recording-controller/index.d.ts +207 -0
  258. package/dist/types/recording-controller/util.d.ts +14 -0
  259. package/dist/types/roap/index.d.ts +77 -0
  260. package/dist/types/roap/request.d.ts +36 -0
  261. package/dist/types/roap/turnDiscovery.d.ts +91 -0
  262. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  263. package/dist/types/rtcMetrics/index.d.ts +46 -0
  264. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  265. package/dist/types/statsAnalyzer/index.d.ts +200 -0
  266. package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
  267. package/dist/types/transcription/index.d.ts +64 -0
  268. package/package.json +23 -20
  269. package/src/annotation/annotation.types.ts +50 -0
  270. package/src/annotation/constants.ts +36 -0
  271. package/src/annotation/index.ts +328 -0
  272. package/src/breakouts/README.md +44 -14
  273. package/src/breakouts/breakout.ts +87 -9
  274. package/src/breakouts/edit-lock-error.ts +25 -0
  275. package/src/breakouts/events.ts +56 -0
  276. package/src/breakouts/index.ts +710 -10
  277. package/src/breakouts/request.ts +55 -0
  278. package/src/breakouts/utils.ts +57 -0
  279. package/src/common/errors/webex-errors.ts +6 -2
  280. package/src/common/logs/logger-proxy.ts +1 -1
  281. package/src/common/queue.ts +22 -8
  282. package/src/config.ts +2 -7
  283. package/src/constants.ts +165 -21
  284. package/src/controls-options-manager/constants.ts +5 -0
  285. package/src/controls-options-manager/enums.ts +18 -0
  286. package/src/controls-options-manager/index.ts +278 -0
  287. package/src/controls-options-manager/types.ts +59 -0
  288. package/src/controls-options-manager/util.ts +300 -0
  289. package/src/index.ts +39 -0
  290. package/src/interpretation/README.md +60 -0
  291. package/src/interpretation/collection.ts +19 -0
  292. package/src/interpretation/index.ts +332 -0
  293. package/src/interpretation/siLanguage.ts +18 -0
  294. package/src/locus-info/controlsUtils.ts +108 -0
  295. package/src/locus-info/index.ts +383 -61
  296. package/src/locus-info/infoUtils.ts +10 -2
  297. package/src/locus-info/mediaSharesUtils.ts +48 -0
  298. package/src/locus-info/parser.ts +224 -39
  299. package/src/locus-info/selfUtils.ts +81 -5
  300. package/src/media/index.ts +87 -140
  301. package/src/media/properties.ts +49 -90
  302. package/src/mediaQualityMetrics/config.ts +379 -377
  303. package/src/meeting/in-meeting-actions.ts +179 -3
  304. package/src/meeting/index.ts +2099 -2083
  305. package/src/meeting/locusMediaRequest.ts +311 -0
  306. package/src/meeting/muteState.ts +228 -132
  307. package/src/meeting/request.ts +105 -115
  308. package/src/meeting/util.ts +511 -397
  309. package/src/meeting-info/index.ts +54 -8
  310. package/src/meeting-info/meeting-info-v2.ts +148 -14
  311. package/src/meeting-info/utilv2.ts +13 -3
  312. package/src/meetings/collection.ts +20 -0
  313. package/src/meetings/index.ts +392 -84
  314. package/src/meetings/meetings.types.ts +12 -0
  315. package/src/meetings/request.ts +2 -0
  316. package/src/meetings/util.ts +103 -4
  317. package/src/member/index.ts +49 -0
  318. package/src/member/types.ts +38 -0
  319. package/src/member/util.ts +127 -25
  320. package/src/members/collection.ts +8 -0
  321. package/src/members/index.ts +107 -6
  322. package/src/members/request.ts +97 -17
  323. package/src/members/types.ts +28 -0
  324. package/src/members/util.ts +319 -240
  325. package/src/metrics/constants.ts +2 -4
  326. package/src/metrics/index.ts +1 -490
  327. package/src/multistream/mediaRequestManager.ts +289 -79
  328. package/src/multistream/receiveSlot.ts +55 -18
  329. package/src/multistream/receiveSlotManager.ts +46 -24
  330. package/src/multistream/remoteMedia.ts +27 -2
  331. package/src/multistream/remoteMediaGroup.ts +59 -0
  332. package/src/multistream/remoteMediaManager.ts +113 -32
  333. package/src/networkQualityMonitor/index.ts +6 -6
  334. package/src/reachability/index.ts +62 -15
  335. package/src/reachability/request.ts +10 -5
  336. package/src/reconnection-manager/index.ts +68 -43
  337. package/src/recording-controller/index.ts +20 -3
  338. package/src/recording-controller/util.ts +26 -9
  339. package/src/roap/index.ts +21 -30
  340. package/src/roap/request.ts +101 -95
  341. package/src/roap/turnDiscovery.ts +47 -25
  342. package/src/rtcMetrics/constants.ts +3 -0
  343. package/src/rtcMetrics/index.ts +100 -0
  344. package/src/statsAnalyzer/global.ts +1 -94
  345. package/src/statsAnalyzer/index.ts +376 -386
  346. package/src/statsAnalyzer/mqaUtil.ts +100 -99
  347. package/test/integration/spec/converged-space-meetings.js +233 -0
  348. package/test/integration/spec/journey.js +336 -259
  349. package/test/integration/spec/space-meeting.js +77 -4
  350. package/test/unit/spec/annotation/index.ts +418 -0
  351. package/test/unit/spec/breakouts/breakout.ts +142 -24
  352. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  353. package/test/unit/spec/breakouts/events.ts +89 -0
  354. package/test/unit/spec/breakouts/index.ts +1545 -48
  355. package/test/unit/spec/breakouts/request.ts +104 -0
  356. package/test/unit/spec/breakouts/utils.js +72 -0
  357. package/test/unit/spec/common/queue.js +31 -2
  358. package/test/unit/spec/controls-options-manager/index.js +287 -0
  359. package/test/unit/spec/controls-options-manager/util.js +582 -0
  360. package/test/unit/spec/fixture/locus.js +1 -0
  361. package/test/unit/spec/interpretation/collection.ts +15 -0
  362. package/test/unit/spec/interpretation/index.ts +589 -0
  363. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  364. package/test/unit/spec/locus-info/controlsUtils.js +316 -43
  365. package/test/unit/spec/locus-info/index.js +1169 -36
  366. package/test/unit/spec/locus-info/infoUtils.js +37 -15
  367. package/test/unit/spec/locus-info/mediaSharesUtils.ts +22 -0
  368. package/test/unit/spec/locus-info/parser.js +62 -22
  369. package/test/unit/spec/locus-info/selfConstant.js +27 -4
  370. package/test/unit/spec/locus-info/selfUtils.js +208 -17
  371. package/test/unit/spec/media/index.ts +138 -28
  372. package/test/unit/spec/meeting/in-meeting-actions.ts +89 -3
  373. package/test/unit/spec/meeting/index.js +3573 -1663
  374. package/test/unit/spec/meeting/locusMediaRequest.ts +438 -0
  375. package/test/unit/spec/meeting/muteState.js +370 -208
  376. package/test/unit/spec/meeting/request.js +339 -44
  377. package/test/unit/spec/meeting/utils.js +456 -53
  378. package/test/unit/spec/meeting-info/index.js +181 -0
  379. package/test/unit/spec/meeting-info/meetinginfov2.js +383 -5
  380. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  381. package/test/unit/spec/meetings/collection.js +14 -0
  382. package/test/unit/spec/meetings/index.js +867 -125
  383. package/test/unit/spec/meetings/utils.js +206 -2
  384. package/test/unit/spec/member/index.js +58 -4
  385. package/test/unit/spec/member/util.js +479 -35
  386. package/test/unit/spec/members/index.js +319 -1
  387. package/test/unit/spec/members/request.js +206 -27
  388. package/test/unit/spec/members/utils.js +184 -0
  389. package/test/unit/spec/metrics/index.js +1 -50
  390. package/test/unit/spec/multistream/mediaRequestManager.ts +803 -162
  391. package/test/unit/spec/multistream/receiveSlot.ts +72 -13
  392. package/test/unit/spec/multistream/receiveSlotManager.ts +58 -28
  393. package/test/unit/spec/multistream/remoteMedia.ts +30 -0
  394. package/test/unit/spec/multistream/remoteMediaGroup.ts +266 -0
  395. package/test/unit/spec/multistream/remoteMediaManager.ts +318 -0
  396. package/test/unit/spec/networkQualityMonitor/index.js +4 -4
  397. package/test/unit/spec/reachability/index.ts +125 -8
  398. package/test/unit/spec/reachability/request.js +66 -0
  399. package/test/unit/spec/reconnection-manager/index.js +59 -6
  400. package/test/unit/spec/recording-controller/index.js +294 -218
  401. package/test/unit/spec/recording-controller/util.js +223 -96
  402. package/test/unit/spec/roap/index.ts +26 -51
  403. package/test/unit/spec/roap/request.ts +196 -85
  404. package/test/unit/spec/roap/turnDiscovery.ts +30 -7
  405. package/test/unit/spec/rtcMetrics/index.ts +60 -0
  406. package/test/unit/spec/stats-analyzer/index.js +92 -41
  407. package/test/utils/constants.js +9 -0
  408. package/test/utils/integrationTestUtils.js +46 -0
  409. package/test/utils/testUtils.js +0 -45
  410. package/test/utils/webex-config.js +4 -0
  411. package/test/utils/webex-test-users.js +6 -3
  412. package/dist/meeting/effectsState.js +0 -262
  413. package/dist/meeting/effectsState.js.map +0 -1
  414. package/dist/metrics/config.js +0 -299
  415. package/dist/metrics/config.js.map +0 -1
  416. package/dist/multistream/multistreamMedia.js +0 -110
  417. package/dist/multistream/multistreamMedia.js.map +0 -1
  418. package/src/index.js +0 -16
  419. package/src/meeting/effectsState.ts +0 -211
  420. package/src/metrics/config.ts +0 -495
  421. package/src/multistream/multistreamMedia.ts +0 -97
  422. package/test/unit/spec/meeting/effectsState.js +0 -285
@@ -9,6 +9,8 @@ import {assert} from '@webex/test-helper-chai';
9
9
  class FakeWcmeSlot extends EventEmitter {
10
10
  public stream;
11
11
 
12
+ public id = 'fake id';
13
+
12
14
  constructor(stream) {
13
15
  super();
14
16
  this.stream = stream;
@@ -28,6 +30,12 @@ describe('ReceiveSlot', () => {
28
30
  receiveSlot = new ReceiveSlot(MediaType.VideoMain, fakeWcmeSlot, findMemberIdCallbackStub);
29
31
  });
30
32
 
33
+ describe('logString', () => {
34
+ it('has a log string', () => {
35
+ assert.equal(receiveSlot.logString, `ReceiveSlot - ${receiveSlot.id}: "fake id"`);
36
+ });
37
+ })
38
+
31
39
  describe('forwards events from underlying wcme receive slot', () => {
32
40
  it('forwards SourceUpdate', () => {
33
41
  let eventEmitted = false;
@@ -57,7 +65,7 @@ describe('ReceiveSlot', () => {
57
65
  });
58
66
 
59
67
  it('has public properties', () => {
60
- assert.strictEqual(receiveSlot.id, 'r1');
68
+ assert.isTrue(receiveSlot.id.startsWith('r'));
61
69
  assert.strictEqual(receiveSlot.mediaType, MediaType.VideoMain);
62
70
  });
63
71
 
@@ -83,22 +91,73 @@ describe('ReceiveSlot', () => {
83
91
  assert.strictEqual(receiveSlot.sourceState, 'live');
84
92
  });
85
93
 
86
- it('resets source related properties when resetSourceState() is called', () => {
87
- const csi = 123456;
88
- const fakeMemberId = '00000001-5555-6666-9012-345678901234';
94
+ describe('findMemberId()', () => {
95
+ it('doesn\'t do anything if csi is not set', () => {
96
+ // by default the receiveSlot does not have any csi or member id
97
+ receiveSlot.findMemberId();
89
98
 
90
- findMemberIdCallbackStub.returns(fakeMemberId);
99
+ assert.notCalled(findMemberIdCallbackStub);
100
+ });
91
101
 
92
- fakeWcmeSlot.emit(WcmeReceiveSlotEvents.SourceUpdate, 'live', csi);
102
+ it('finds a member id if member id is undefined and CSI is known', () => {
103
+ let emittedSourceUpdateEvent = null;
93
104
 
94
- assert.strictEqual(receiveSlot.memberId, fakeMemberId);
95
- assert.strictEqual(receiveSlot.csi, csi);
96
- assert.strictEqual(receiveSlot.sourceState, 'live');
105
+ // setup receiveSlot to have a csi without a member id
106
+ const csi = 12345;
107
+ const fakeMemberId = 'aaa-bbb-ccc-ddd';
108
+ fakeWcmeSlot.emit(WcmeReceiveSlotEvents.SourceUpdate, 'live', csi);
109
+ findMemberIdCallbackStub.reset();
110
+ findMemberIdCallbackStub.returns(fakeMemberId);
97
111
 
98
- receiveSlot.resetSourceState();
112
+ receiveSlot.on(ReceiveSlotEvents.SourceUpdate, (data) => {
113
+ emittedSourceUpdateEvent = data;
114
+ });
99
115
 
100
- assert.strictEqual(receiveSlot.memberId, undefined);
101
- assert.strictEqual(receiveSlot.csi, undefined);
102
- assert.strictEqual(receiveSlot.sourceState, 'no source');
116
+ receiveSlot.findMemberId();
117
+
118
+ assert.calledOnce(findMemberIdCallbackStub);
119
+ assert.calledWith(findMemberIdCallbackStub, csi);
120
+
121
+ assert.deepEqual(emittedSourceUpdateEvent, {
122
+ state: 'live',
123
+ csi,
124
+ memberId: fakeMemberId,
125
+ });
126
+
127
+ });
128
+
129
+ it('doesn\'t do anything if member id already set', () => {
130
+ // setup receiveSlot to have a csi and a member id
131
+ const csi = 12345;
132
+ const memberId = '12345678-1234-5678-9012-345678901234';
133
+
134
+ findMemberIdCallbackStub.returns(memberId);
135
+
136
+ fakeWcmeSlot.emit(WcmeReceiveSlotEvents.SourceUpdate, 'live', csi);
137
+ findMemberIdCallbackStub.reset();
138
+
139
+ receiveSlot.findMemberId();
140
+
141
+ assert.notCalled(findMemberIdCallbackStub);
142
+ });
143
+ });
144
+
145
+ describe('setMaxFs()', () => {
146
+ it('emits the correct event', () => {
147
+ sinon.stub(receiveSlot, 'emit');
148
+ receiveSlot.setMaxFs(100);
149
+
150
+ assert.calledOnceWithExactly(
151
+ receiveSlot.emit,
152
+ {
153
+ file: 'meeting/receiveSlot',
154
+ function: 'findMemberId',
155
+ },
156
+ ReceiveSlotEvents.MaxFsUpdate,
157
+ {
158
+ maxFs: 100,
159
+ }
160
+ );
161
+ })
103
162
  });
104
163
  });
@@ -1,35 +1,29 @@
1
1
  import sinon from 'sinon';
2
2
  import {assert} from '@webex/test-helper-chai';
3
3
  import {MediaType} from '@webex/internal-media-core';
4
+ import {ReceiveSlot} from '@webex/plugin-meetings/src/multistream/receiveSlot';
4
5
  import {ReceiveSlotManager} from '@webex/plugin-meetings/src/multistream/receiveSlotManager';
5
6
  import * as ReceiveSlotModule from '@webex/plugin-meetings/src/multistream/receiveSlot';
6
7
 
7
8
  describe('ReceiveSlotManager', () => {
8
- let fakeMeeting;
9
9
  let fakeWcmeSlot;
10
10
  let fakeReceiveSlots;
11
11
  let mockReceiveSlotCtor;
12
12
  let receiveSlotManager;
13
+ let createSlotCallbackStub;
14
+ let findMemberIdCallbackStub;
13
15
 
14
16
  beforeEach(() => {
15
17
  fakeWcmeSlot = {
16
- id: 'fake wcme slot',
17
- };
18
- fakeMeeting = {
19
- mediaProperties: {
20
- webrtcMediaConnection: {
21
- createReceiveSlot: sinon.stub().resolves(fakeWcmeSlot),
22
- },
23
- },
24
- members: {
25
- findMemberByCsi: sinon.stub(),
26
- },
18
+ id: {ssrc: 1},
27
19
  };
28
20
  fakeReceiveSlots = [];
29
21
  mockReceiveSlotCtor = sinon.stub(ReceiveSlotModule, 'ReceiveSlot').callsFake((mediaType) => {
30
22
  const fakeReceiveSlot = {
31
23
  id: `fake sdk receive slot ${fakeReceiveSlots.length + 1}`,
32
24
  mediaType,
25
+ findMemberId: sinon.stub(),
26
+ wcmeReceiveSlot: fakeWcmeSlot,
33
27
  };
34
28
 
35
29
  fakeReceiveSlots.push(fakeReceiveSlot);
@@ -37,7 +31,10 @@ describe('ReceiveSlotManager', () => {
37
31
  return fakeReceiveSlot;
38
32
  });
39
33
 
40
- receiveSlotManager = new ReceiveSlotManager(fakeMeeting);
34
+ createSlotCallbackStub = sinon.stub().resolves(fakeWcmeSlot);
35
+ findMemberIdCallbackStub = sinon.stub();
36
+
37
+ receiveSlotManager = new ReceiveSlotManager(createSlotCallbackStub, findMemberIdCallbackStub);
41
38
  });
42
39
 
43
40
  afterEach(() => {
@@ -45,7 +42,7 @@ describe('ReceiveSlotManager', () => {
45
42
  });
46
43
 
47
44
  it('rejects if there is no media connection', async () => {
48
- fakeMeeting.mediaProperties.webrtcMediaConnection = null;
45
+ createSlotCallbackStub.rejects(new Error('Webrtc media connection is missing'));
49
46
 
50
47
  assert.isRejected(
51
48
  receiveSlotManager.allocateSlot(MediaType.VideoMain),
@@ -58,14 +55,14 @@ describe('ReceiveSlotManager', () => {
58
55
 
59
56
  const slot = await receiveSlotManager.allocateSlot(MediaType.VideoMain);
60
57
 
61
- assert.calledOnce(fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot);
58
+ assert.calledOnce(createSlotCallbackStub);
62
59
  assert.calledWith(
63
- fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot,
60
+ createSlotCallbackStub,
64
61
  MediaType.VideoMain
65
62
  );
66
63
 
67
64
  assert.calledOnce(mockReceiveSlotCtor);
68
- assert.calledWith(mockReceiveSlotCtor, MediaType.VideoMain, fakeWcmeSlot, sinon.match.func);
65
+ assert.calledWith(mockReceiveSlotCtor, MediaType.VideoMain, fakeWcmeSlot, findMemberIdCallbackStub);
69
66
  assert.strictEqual(slot, fakeReceiveSlots[0]);
70
67
 
71
68
  assert.deepEqual(receiveSlotManager.getStats(), {
@@ -77,7 +74,7 @@ describe('ReceiveSlotManager', () => {
77
74
  it('reuses previously freed slot when allocateSlot() is called and a free slot is available', async () => {
78
75
  const slot1 = await receiveSlotManager.allocateSlot(MediaType.VideoMain);
79
76
 
80
- assert.calledOnce(fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot);
77
+ assert.calledOnce(createSlotCallbackStub);
81
78
  assert.calledOnce(mockReceiveSlotCtor);
82
79
  assert.strictEqual(slot1, fakeReceiveSlots[0]);
83
80
 
@@ -89,13 +86,13 @@ describe('ReceiveSlotManager', () => {
89
86
  numFreeSlots: {'VIDEO-MAIN': 1},
90
87
  });
91
88
 
92
- fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot.resetHistory();
89
+ createSlotCallbackStub.resetHistory();
93
90
  mockReceiveSlotCtor.resetHistory();
94
91
 
95
92
  // allocate another slot, this time the previous one should be returned instead of allocating any new ones
96
93
  const slot2 = await receiveSlotManager.allocateSlot(MediaType.VideoMain);
97
94
 
98
- assert.notCalled(fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot);
95
+ assert.notCalled(createSlotCallbackStub);
99
96
  assert.notCalled(mockReceiveSlotCtor);
100
97
 
101
98
  // verify that in fact we got the same slot again
@@ -110,7 +107,7 @@ describe('ReceiveSlotManager', () => {
110
107
  it('does not reuse any slots after reset() is called', async () => {
111
108
  const slot1 = await receiveSlotManager.allocateSlot(MediaType.VideoMain);
112
109
 
113
- assert.calledOnce(fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot);
110
+ assert.calledOnce(createSlotCallbackStub);
114
111
  assert.calledOnce(mockReceiveSlotCtor);
115
112
  assert.strictEqual(slot1, fakeReceiveSlots[0]);
116
113
 
@@ -119,7 +116,7 @@ describe('ReceiveSlotManager', () => {
119
116
  receiveSlotManager.reset();
120
117
 
121
118
  // reset the mocks and set the ReceiveSlot constructor to return a different slot
122
- fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot.resetHistory();
119
+ createSlotCallbackStub.resetHistory();
123
120
  mockReceiveSlotCtor.resetHistory();
124
121
 
125
122
  assert.deepEqual(receiveSlotManager.getStats(), {numAllocatedSlots: {}, numFreeSlots: {}});
@@ -127,7 +124,7 @@ describe('ReceiveSlotManager', () => {
127
124
  // allocate another slot, because we called reset(), the old free slot should not be reused
128
125
  const slot2 = await receiveSlotManager.allocateSlot(MediaType.VideoMain);
129
126
 
130
- assert.calledOnce(fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot);
127
+ assert.calledOnce(createSlotCallbackStub);
131
128
  assert.calledOnce(mockReceiveSlotCtor);
132
129
 
133
130
  // verify that in fact we got a brand new slot
@@ -142,25 +139,25 @@ describe('ReceiveSlotManager', () => {
142
139
  it('does not reuse slots if they have different media type', async () => {
143
140
  const slot1 = await receiveSlotManager.allocateSlot(MediaType.VideoMain);
144
141
 
145
- assert.calledOnce(fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot);
142
+ assert.calledOnce(createSlotCallbackStub);
146
143
  assert.calledOnce(mockReceiveSlotCtor);
147
144
 
148
145
  receiveSlotManager.releaseSlot(slot1);
149
146
 
150
- fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot.resetHistory();
147
+ createSlotCallbackStub.resetHistory();
151
148
  mockReceiveSlotCtor.resetHistory();
152
149
 
153
150
  // allocate another slot, this time for main audio, so it should be a completely new slot
154
151
  const slot2 = await receiveSlotManager.allocateSlot(MediaType.AudioMain);
155
152
 
156
- assert.calledOnce(fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot);
153
+ assert.calledOnce(createSlotCallbackStub);
157
154
  assert.calledWith(
158
- fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot,
155
+ createSlotCallbackStub,
159
156
  MediaType.AudioMain
160
157
  );
161
158
 
162
159
  assert.calledOnce(mockReceiveSlotCtor);
163
- assert.calledWith(mockReceiveSlotCtor, MediaType.AudioMain, fakeWcmeSlot, sinon.match.func);
160
+ assert.calledWith(mockReceiveSlotCtor, MediaType.AudioMain, fakeWcmeSlot, findMemberIdCallbackStub);
164
161
 
165
162
  // verify that in fact we got a brand new slot
166
163
  assert.strictEqual(slot2, fakeReceiveSlots[1]);
@@ -170,4 +167,37 @@ describe('ReceiveSlotManager', () => {
170
167
  numFreeSlots: {'VIDEO-MAIN': 1},
171
168
  });
172
169
  });
170
+
171
+ describe('updateMemberIds', () => {
172
+ it('calls findMemberId() on all allocated receive slots', async () => {
173
+ const audioSlots: ReceiveSlot[] = [];
174
+ const videoSlots: ReceiveSlot[] = [];
175
+
176
+ // allocate a bunch of receive slots
177
+ audioSlots.push(await receiveSlotManager.allocateSlot(MediaType.AudioMain));
178
+ audioSlots.push(await receiveSlotManager.allocateSlot(MediaType.AudioMain));
179
+ videoSlots.push(await receiveSlotManager.allocateSlot(MediaType.VideoMain));
180
+ videoSlots.push(await receiveSlotManager.allocateSlot(MediaType.VideoMain));
181
+ videoSlots.push(await receiveSlotManager.allocateSlot(MediaType.VideoMain));
182
+
183
+ receiveSlotManager.updateMemberIds();
184
+
185
+ assert.strictEqual(audioSlots.length, 2);
186
+ assert.strictEqual(videoSlots.length, 3);
187
+
188
+ assert.strictEqual(fakeReceiveSlots.length, audioSlots.length + videoSlots.length);
189
+
190
+ fakeReceiveSlots.forEach((slot) => {
191
+ assert.calledOnce(slot.findMemberId);
192
+ });
193
+ });
194
+ });
195
+
196
+ describe('findReceiveSlotBySsrc', () => {
197
+ it('finds a receive slot with a specific id', async () => {
198
+ await receiveSlotManager.allocateSlot(MediaType.VideoMain);
199
+ assert.exists(receiveSlotManager.findReceiveSlotBySsrc(1));
200
+ assert.strictEqual(receiveSlotManager.findReceiveSlotBySsrc(2), undefined);
201
+ });
202
+ });
173
203
  });
@@ -6,6 +6,7 @@ import {RemoteMedia, RemoteMediaEvents} from '@webex/plugin-meetings/src/multist
6
6
  import {ReceiveSlotEvents} from '@webex/plugin-meetings/src/multistream/receiveSlot';
7
7
  import sinon from 'sinon';
8
8
  import {assert} from '@webex/test-helper-chai';
9
+ import { forEach } from 'lodash';
9
10
 
10
11
  describe('RemoteMedia', () => {
11
12
  let remoteMedia;
@@ -21,6 +22,7 @@ describe('RemoteMedia', () => {
21
22
  fakeReceiveSlot.csi = 999;
22
23
  fakeReceiveSlot.sourceState = 'avatar';
23
24
  fakeReceiveSlot.stream = fakeStream;
25
+ fakeReceiveSlot.setMaxFs = sinon.stub();
24
26
 
25
27
  fakeMediaRequestManager = {
26
28
  addRequest: sinon.stub(),
@@ -222,4 +224,32 @@ describe('RemoteMedia', () => {
222
224
  });
223
225
  });
224
226
  });
227
+
228
+ describe('setSizeHint()', () => {
229
+
230
+ it('works if the receive slot is undefined', () => {
231
+ remoteMedia.receiveSlot = undefined;
232
+ remoteMedia.setSizeHint(100, 100);
233
+ });
234
+
235
+ forEach(
236
+ [
237
+ {height: 134, fs: 60},
238
+ {height: 135, fs: 240},
239
+ {height: 269, fs: 240},
240
+ {height: 270, fs: 920},
241
+ {height: 539, fs: 920},
242
+ {height: 540, fs: 3600},
243
+ {height: 720, fs: 3600},
244
+ {height: 721, fs: 8192},
245
+ ],
246
+ ({height, fs}) => {
247
+ it(`sets the max fs to ${fs} correctly when height is ${height}`, () => {
248
+ remoteMedia.setSizeHint(100, height);
249
+
250
+ assert.calledOnceWithExactly(fakeReceiveSlot.setMaxFs, fs);
251
+ });
252
+ }
253
+ );
254
+ });
225
255
  });
@@ -97,6 +97,272 @@ describe('RemoteMediaGroup', () => {
97
97
  });
98
98
  });
99
99
 
100
+ describe('setPreferLiveVideo', () => {
101
+ it('updates prefer live video', () => {
102
+
103
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
104
+ resolution: 'medium',
105
+ preferLiveVideo: false,
106
+ });
107
+ fakeMediaRequestManager.addRequest.resetHistory();
108
+ group.setPreferLiveVideo(true, false);
109
+
110
+ assert.calledOnce(fakeMediaRequestManager.cancelRequest);
111
+
112
+ assert.calledOnce(fakeMediaRequestManager.addRequest);
113
+
114
+ assert.calledWith(
115
+ fakeMediaRequestManager.addRequest,
116
+ sinon.match({
117
+ policyInfo: sinon.match({
118
+ policy: 'active-speaker',
119
+ priority: 255,
120
+ preferLiveVideo: true
121
+ }),
122
+ receiveSlots: fakeReceiveSlots,
123
+ codecInfo: sinon.match({
124
+ codec: 'h264',
125
+ maxFs: 3600,
126
+ }),
127
+ }),
128
+ false,
129
+ );
130
+ });
131
+
132
+ it('does not call add request when prefer live video has not changed', () => {
133
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
134
+ resolution: 'medium',
135
+ preferLiveVideo: true,
136
+ });
137
+ fakeMediaRequestManager.addRequest.resetHistory();
138
+ group.setPreferLiveVideo(true, false);
139
+
140
+ assert.notCalled(fakeMediaRequestManager.cancelRequest);
141
+
142
+ assert.notCalled(fakeMediaRequestManager.addRequest);
143
+ });
144
+
145
+ });
146
+
147
+ describe('setActiveSpeakerCsis', () => {
148
+ it('checks when there is a csi and remote media is not in pinned array', () => {
149
+ const PINNED_INDEX = 2;
150
+ const CSI = 11111;
151
+
152
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
153
+ resolution: 'medium',
154
+ preferLiveVideo: true,
155
+ });
156
+
157
+ // initially nothing should be pinned
158
+ assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS); // by default should return 'all'
159
+ assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
160
+ assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS);
161
+ assert.strictEqual(group.getRemoteMedia('pinned').length, 0);
162
+
163
+ const remoteMedia = group.getRemoteMedia('all')[PINNED_INDEX];
164
+
165
+ resetHistory();
166
+
167
+ group.setActiveSpeakerCsis([{remoteMedia, csi: CSI}], false);
168
+
169
+ assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS); // by default should return 'all'
170
+ assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
171
+ assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS - 1);
172
+ assert.strictEqual(group.getRemoteMedia('pinned').length, 1);
173
+
174
+ assert.strictEqual(group.isPinned(remoteMedia), true);
175
+ // now check that correct media requests were sent...
176
+
177
+ const expectedReceiverSelectedSlots = [fakeReceiveSlots[PINNED_INDEX]];
178
+ const expectedActiveSpeakerReceiveSlots = fakeReceiveSlots.filter(
179
+ (_, idx) => idx !== PINNED_INDEX
180
+ );
181
+
182
+ // the previous active speaker media request for the group should have been cancelled
183
+ assert.calledOnce(fakeMediaRequestManager.cancelRequest);
184
+ assert.calledWith(fakeMediaRequestManager.cancelRequest, 'fake active speaker request 1');
185
+ // a new one should be sent for active speaker and for receiver selected
186
+ assert.calledTwice(fakeMediaRequestManager.addRequest);
187
+ assert.calledWith(
188
+ fakeMediaRequestManager.addRequest,
189
+ sinon.match({
190
+ policyInfo: sinon.match({
191
+ policy: 'active-speaker',
192
+ priority: 255,
193
+ }),
194
+ receiveSlots: expectedActiveSpeakerReceiveSlots,
195
+ codecInfo: sinon.match({
196
+ codec: 'h264',
197
+ maxFs: 3600,
198
+ }),
199
+ })
200
+ );
201
+ assert.calledWith(
202
+ fakeMediaRequestManager.addRequest,
203
+ sinon.match({
204
+ policyInfo: sinon.match({
205
+ policy: 'receiver-selected',
206
+ csi: CSI,
207
+ }),
208
+ receiveSlots: expectedReceiverSelectedSlots,
209
+ codecInfo: sinon.match({
210
+ codec: 'h264',
211
+ maxFs: 3600,
212
+ }),
213
+ })
214
+ );
215
+ assert.notCalled(fakeMediaRequestManager.commit);
216
+ });
217
+
218
+ it('checks when there is csi and remoteMedia is in pinned array', () => {
219
+ const PINNED_INDEX = 4;
220
+
221
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
222
+ resolution: 'medium',
223
+ preferLiveVideo: true,
224
+ });
225
+
226
+ // take one instance of remote media from the group
227
+ const remoteMedia = group.getRemoteMedia('all')[PINNED_INDEX];
228
+
229
+ resetHistory();
230
+
231
+ // pin it so that it is in pinned array
232
+ group.setActiveSpeakerCsis([{remoteMedia, csi: 1234}], false);
233
+
234
+ assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS); // by default should return 'all'
235
+ assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
236
+ assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS - 1);
237
+ assert.strictEqual(group.getRemoteMedia('pinned').length, 1);
238
+
239
+ resetHistory();
240
+ // normally this would result in the underlying receive slot csi to be updated, because we're using fake
241
+ // receive slots, we have to do that manually:
242
+ fakeReceiveSlots[PINNED_INDEX].csi = 1234;
243
+ const expectedReceiverSelectedSlots = [fakeReceiveSlots[PINNED_INDEX]];
244
+
245
+ // pin again to same CSI
246
+ group.setActiveSpeakerCsis([{remoteMedia, csi: 1234}], false);
247
+
248
+ assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS); // by default should return 'all'
249
+ assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
250
+ assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS - 1);
251
+ assert.strictEqual(group.getRemoteMedia('pinned').length, 1);
252
+
253
+ assert.strictEqual(group.isPinned(remoteMedia), true);
254
+
255
+ assert.calledTwice(fakeMediaRequestManager.cancelRequest);
256
+ assert.calledWith(fakeMediaRequestManager.cancelRequest, 'fake receiver selected request 1');
257
+
258
+ assert.calledWith(
259
+ fakeMediaRequestManager.addRequest,
260
+ sinon.match({
261
+ policyInfo: sinon.match({
262
+ policy: 'receiver-selected',
263
+ csi: 1234,
264
+ }),
265
+ receiveSlots: expectedReceiverSelectedSlots,
266
+ codecInfo: sinon.match({
267
+ codec: 'h264',
268
+ maxFs: 3600,
269
+ }),
270
+ })
271
+ );
272
+ assert.notCalled(fakeMediaRequestManager.commit);
273
+ });
274
+
275
+ it('checks setActiveSpeakerCsis with array of remoteMedia to pin and unpin', () => {
276
+ const PINNED_INDEX = 2;
277
+ const PINNED_INDEX2 = 0;
278
+ const CSI = 11111;
279
+ const CSI2 = 12345;
280
+
281
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
282
+ resolution: 'medium',
283
+ preferLiveVideo: true,
284
+ });
285
+
286
+ // initially nothing should be pinned
287
+ assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS); // by default should return 'all'
288
+ assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
289
+ assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS);
290
+ assert.strictEqual(group.getRemoteMedia('pinned').length, 0);
291
+
292
+ const remoteMedia = group.getRemoteMedia('all')[PINNED_INDEX];
293
+
294
+ const remoteMedia2 = group.getRemoteMedia('all')[PINNED_INDEX2];
295
+
296
+ const remoteMedisCsis = [{remoteMedia, csi: CSI}, {remoteMedia: remoteMedia2, csi: CSI2}];
297
+
298
+ group.setActiveSpeakerCsis(remoteMedisCsis, false);
299
+
300
+ assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS);
301
+ assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
302
+ assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS - 2);
303
+ assert.strictEqual(group.getRemoteMedia('pinned').length, 2);
304
+
305
+ assert.strictEqual(group.isPinned(remoteMedia), true);
306
+ assert.strictEqual(group.isPinned(remoteMedia2), true);
307
+
308
+ resetHistory();
309
+
310
+ group.setActiveSpeakerCsis([{remoteMedia}], false);
311
+
312
+ // one pane should still remain pinned
313
+ assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS);
314
+ assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
315
+ assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS - 1);
316
+ assert.strictEqual(group.getRemoteMedia('pinned').length, 1);
317
+ assert.strictEqual(group.isPinned(remoteMedia), false);
318
+ assert.strictEqual(group.isPinned(remoteMedia2), true);
319
+
320
+ assert.calledTwice(fakeMediaRequestManager.cancelRequest);
321
+ assert.calledWith(fakeMediaRequestManager.cancelRequest, 'fake receiver selected request 1');
322
+ assert.notCalled(fakeMediaRequestManager.commit);
323
+ });
324
+
325
+ it('check commit is only called once', () => {
326
+ const PINNED_INDEX = 2;
327
+ const PINNED_INDEX2 = 0;
328
+ const CSI = 11111;
329
+ const CSI2 = 12345;
330
+
331
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
332
+ resolution: 'medium',
333
+ preferLiveVideo: true,
334
+ });
335
+
336
+ const remoteMedia = group.getRemoteMedia('all')[PINNED_INDEX];
337
+
338
+ resetHistory();
339
+
340
+ const remoteMedia2 = group.getRemoteMedia('all')[PINNED_INDEX2];
341
+
342
+ const remoteMedisCsis = [{remoteMedia, csi: CSI}, {remoteMedia: remoteMedia2, csi: CSI2}, {remoteMedia}];
343
+
344
+ group.setActiveSpeakerCsis(remoteMedisCsis, true);
345
+
346
+ assert.calledOnce(fakeMediaRequestManager.commit);
347
+ });
348
+
349
+ it('throws when remoteMedia id is not in unpinned and pinned array - csi is there', () => {
350
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
351
+ resolution: 'medium',
352
+ preferLiveVideo: true,
353
+ });
354
+ assert.throws(() => group.setActiveSpeakerCsis([{remoteMedia: {id: 'r1'} as any, csi: 123}], false), 'failed to pin a remote media object r1, because it is not found in this remote media group');
355
+ });
356
+
357
+ it('throws when remoteMedia id is not in unpinned and pinned array - csi is not there', () => {
358
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
359
+ resolution: 'medium',
360
+ preferLiveVideo: true,
361
+ });
362
+ assert.throws(() => group.setActiveSpeakerCsis([{remoteMedia: {id: 'r1'} as any}], false), 'failed to unpin a remote media object r1, because it is not found in this remote media group');
363
+ });
364
+ });
365
+
100
366
  describe('pinning', () => {
101
367
  it('works as expected', () => {
102
368
  const PINNED_INDEX = 2;