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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (393) hide show
  1. package/README.md +58 -8
  2. package/dist/annotation/annotation.types.js +7 -0
  3. package/dist/annotation/annotation.types.js.map +1 -0
  4. package/dist/annotation/constants.js +49 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +342 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +94 -15
  9. package/dist/breakouts/breakout.js.map +1 -1
  10. package/dist/breakouts/events.js +45 -0
  11. package/dist/breakouts/events.js.map +1 -0
  12. package/dist/breakouts/index.js +671 -81
  13. package/dist/breakouts/index.js.map +1 -1
  14. package/dist/breakouts/utils.js +45 -1
  15. package/dist/breakouts/utils.js.map +1 -1
  16. package/dist/common/errors/no-meeting-info.js +51 -0
  17. package/dist/common/errors/no-meeting-info.js.map +1 -0
  18. package/dist/common/errors/reclaim-host-role-errors.js +158 -0
  19. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  20. package/dist/common/errors/webex-errors.js +48 -7
  21. package/dist/common/errors/webex-errors.js.map +1 -1
  22. package/dist/common/logs/logger-proxy.js +1 -1
  23. package/dist/common/logs/logger-proxy.js.map +1 -1
  24. package/dist/common/logs/request.js +5 -1
  25. package/dist/common/logs/request.js.map +1 -1
  26. package/dist/common/queue.js +24 -9
  27. package/dist/common/queue.js.map +1 -1
  28. package/dist/config.js +5 -10
  29. package/dist/config.js.map +1 -1
  30. package/dist/constants.js +242 -33
  31. package/dist/constants.js.map +1 -1
  32. package/dist/controls-options-manager/enums.js +14 -2
  33. package/dist/controls-options-manager/enums.js.map +1 -1
  34. package/dist/controls-options-manager/index.js +109 -15
  35. package/dist/controls-options-manager/index.js.map +1 -1
  36. package/dist/controls-options-manager/types.js +7 -0
  37. package/dist/controls-options-manager/types.js.map +1 -0
  38. package/dist/controls-options-manager/util.js +309 -18
  39. package/dist/controls-options-manager/util.js.map +1 -1
  40. package/dist/index.js +110 -2
  41. package/dist/index.js.map +1 -1
  42. package/dist/interceptors/index.js +15 -0
  43. package/dist/interceptors/index.js.map +1 -0
  44. package/dist/interceptors/locusRetry.js +93 -0
  45. package/dist/interceptors/locusRetry.js.map +1 -0
  46. package/dist/interpretation/collection.js +23 -0
  47. package/dist/interpretation/collection.js.map +1 -0
  48. package/dist/interpretation/index.js +380 -0
  49. package/dist/interpretation/index.js.map +1 -0
  50. package/dist/interpretation/siLanguage.js +25 -0
  51. package/dist/interpretation/siLanguage.js.map +1 -0
  52. package/dist/locus-info/controlsUtils.js +91 -2
  53. package/dist/locus-info/controlsUtils.js.map +1 -1
  54. package/dist/locus-info/index.js +386 -62
  55. package/dist/locus-info/index.js.map +1 -1
  56. package/dist/locus-info/infoUtils.js +7 -1
  57. package/dist/locus-info/infoUtils.js.map +1 -1
  58. package/dist/locus-info/mediaSharesUtils.js +71 -1
  59. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  60. package/dist/locus-info/parser.js +249 -72
  61. package/dist/locus-info/parser.js.map +1 -1
  62. package/dist/locus-info/selfUtils.js +89 -14
  63. package/dist/locus-info/selfUtils.js.map +1 -1
  64. package/dist/media/index.js +65 -102
  65. package/dist/media/index.js.map +1 -1
  66. package/dist/media/properties.js +73 -124
  67. package/dist/media/properties.js.map +1 -1
  68. package/dist/mediaQualityMetrics/config.js +135 -330
  69. package/dist/mediaQualityMetrics/config.js.map +1 -1
  70. package/dist/meeting/in-meeting-actions.js +86 -2
  71. package/dist/meeting/in-meeting-actions.js.map +1 -1
  72. package/dist/meeting/index.js +4075 -2827
  73. package/dist/meeting/index.js.map +1 -1
  74. package/dist/meeting/locusMediaRequest.js +292 -0
  75. package/dist/meeting/locusMediaRequest.js.map +1 -0
  76. package/dist/meeting/muteState.js +224 -136
  77. package/dist/meeting/muteState.js.map +1 -1
  78. package/dist/meeting/request.js +177 -152
  79. package/dist/meeting/request.js.map +1 -1
  80. package/dist/meeting/util.js +672 -417
  81. package/dist/meeting/util.js.map +1 -1
  82. package/dist/meeting-info/index.js +73 -7
  83. package/dist/meeting-info/index.js.map +1 -1
  84. package/dist/meeting-info/meeting-info-v2.js +192 -51
  85. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  86. package/dist/meeting-info/util.js +1 -1
  87. package/dist/meeting-info/util.js.map +1 -1
  88. package/dist/meeting-info/utilv2.js +36 -36
  89. package/dist/meeting-info/utilv2.js.map +1 -1
  90. package/dist/meetings/collection.js +39 -0
  91. package/dist/meetings/collection.js.map +1 -1
  92. package/dist/meetings/index.js +484 -119
  93. package/dist/meetings/index.js.map +1 -1
  94. package/dist/meetings/meetings.types.js +7 -0
  95. package/dist/meetings/meetings.types.js.map +1 -0
  96. package/dist/meetings/request.js +2 -0
  97. package/dist/meetings/request.js.map +1 -1
  98. package/dist/meetings/util.js +73 -7
  99. package/dist/meetings/util.js.map +1 -1
  100. package/dist/member/index.js +58 -0
  101. package/dist/member/index.js.map +1 -1
  102. package/dist/member/types.js +25 -0
  103. package/dist/member/types.js.map +1 -0
  104. package/dist/member/util.js +132 -25
  105. package/dist/member/util.js.map +1 -1
  106. package/dist/members/collection.js +10 -0
  107. package/dist/members/collection.js.map +1 -1
  108. package/dist/members/index.js +102 -6
  109. package/dist/members/index.js.map +1 -1
  110. package/dist/members/request.js +106 -38
  111. package/dist/members/request.js.map +1 -1
  112. package/dist/members/types.js +15 -0
  113. package/dist/members/types.js.map +1 -0
  114. package/dist/members/util.js +326 -232
  115. package/dist/members/util.js.map +1 -1
  116. package/dist/metrics/constants.js +18 -1
  117. package/dist/metrics/constants.js.map +1 -1
  118. package/dist/metrics/index.js +1 -446
  119. package/dist/metrics/index.js.map +1 -1
  120. package/dist/multistream/mediaRequestManager.js +223 -32
  121. package/dist/multistream/mediaRequestManager.js.map +1 -1
  122. package/dist/multistream/receiveSlot.js +10 -0
  123. package/dist/multistream/receiveSlot.js.map +1 -1
  124. package/dist/multistream/receiveSlotManager.js +39 -36
  125. package/dist/multistream/receiveSlotManager.js.map +1 -1
  126. package/dist/multistream/remoteMedia.js +3 -1
  127. package/dist/multistream/remoteMedia.js.map +1 -1
  128. package/dist/multistream/remoteMediaGroup.js +76 -5
  129. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  130. package/dist/multistream/remoteMediaManager.js +366 -104
  131. package/dist/multistream/remoteMediaManager.js.map +1 -1
  132. package/dist/multistream/sendSlotManager.js +255 -0
  133. package/dist/multistream/sendSlotManager.js.map +1 -0
  134. package/dist/reachability/clusterReachability.js +356 -0
  135. package/dist/reachability/clusterReachability.js.map +1 -0
  136. package/dist/reachability/index.js +263 -390
  137. package/dist/reachability/index.js.map +1 -1
  138. package/dist/reachability/request.js +6 -4
  139. package/dist/reachability/request.js.map +1 -1
  140. package/dist/reachability/util.js +29 -0
  141. package/dist/reachability/util.js.map +1 -0
  142. package/dist/reconnection-manager/index.js +266 -202
  143. package/dist/reconnection-manager/index.js.map +1 -1
  144. package/dist/recording-controller/index.js +21 -2
  145. package/dist/recording-controller/index.js.map +1 -1
  146. package/dist/recording-controller/util.js +9 -8
  147. package/dist/recording-controller/util.js.map +1 -1
  148. package/dist/roap/index.js +51 -28
  149. package/dist/roap/index.js.map +1 -1
  150. package/dist/roap/request.js +48 -64
  151. package/dist/roap/request.js.map +1 -1
  152. package/dist/roap/turnDiscovery.js +220 -70
  153. package/dist/roap/turnDiscovery.js.map +1 -1
  154. package/dist/rtcMetrics/constants.js +12 -0
  155. package/dist/rtcMetrics/constants.js.map +1 -0
  156. package/dist/rtcMetrics/index.js +179 -0
  157. package/dist/rtcMetrics/index.js.map +1 -0
  158. package/dist/statsAnalyzer/index.js +357 -295
  159. package/dist/statsAnalyzer/index.js.map +1 -1
  160. package/dist/statsAnalyzer/mqaUtil.js +296 -156
  161. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  162. package/dist/types/annotation/annotation.types.d.ts +42 -0
  163. package/dist/types/annotation/constants.d.ts +31 -0
  164. package/dist/types/annotation/index.d.ts +117 -0
  165. package/dist/types/breakouts/events.d.ts +8 -0
  166. package/dist/types/breakouts/utils.d.ts +14 -0
  167. package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
  168. package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
  169. package/dist/types/common/errors/webex-errors.d.ts +25 -1
  170. package/dist/types/common/logs/request.d.ts +2 -0
  171. package/dist/types/common/queue.d.ts +9 -7
  172. package/dist/types/config.d.ts +2 -7
  173. package/dist/types/constants.d.ts +203 -31
  174. package/dist/types/controls-options-manager/enums.d.ts +11 -1
  175. package/dist/types/controls-options-manager/index.d.ts +17 -1
  176. package/dist/types/controls-options-manager/types.d.ts +43 -0
  177. package/dist/types/controls-options-manager/util.d.ts +1 -7
  178. package/dist/types/index.d.ts +6 -5
  179. package/dist/types/interceptors/index.d.ts +2 -0
  180. package/dist/types/interceptors/locusRetry.d.ts +27 -0
  181. package/dist/types/interpretation/collection.d.ts +5 -0
  182. package/dist/types/interpretation/index.d.ts +5 -0
  183. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  184. package/dist/types/locus-info/index.d.ts +57 -4
  185. package/dist/types/locus-info/parser.d.ts +66 -6
  186. package/dist/types/media/index.d.ts +2 -0
  187. package/dist/types/media/properties.d.ts +34 -49
  188. package/dist/types/mediaQualityMetrics/config.d.ts +99 -223
  189. package/dist/types/meeting/in-meeting-actions.d.ts +86 -2
  190. package/dist/types/meeting/index.d.ts +567 -496
  191. package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
  192. package/dist/types/meeting/muteState.d.ts +93 -25
  193. package/dist/types/meeting/request.d.ts +64 -43
  194. package/dist/types/meeting/util.d.ts +117 -1
  195. package/dist/types/meeting-info/index.d.ts +13 -1
  196. package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
  197. package/dist/types/meetings/collection.d.ts +17 -0
  198. package/dist/types/meetings/index.d.ts +113 -21
  199. package/dist/types/meetings/meetings.types.d.ts +4 -0
  200. package/dist/types/member/index.d.ts +14 -0
  201. package/dist/types/member/types.d.ts +32 -0
  202. package/dist/types/members/collection.d.ts +5 -0
  203. package/dist/types/members/index.d.ts +35 -2
  204. package/dist/types/members/request.d.ts +73 -9
  205. package/dist/types/members/types.d.ts +25 -0
  206. package/dist/types/members/util.d.ts +214 -1
  207. package/dist/types/metrics/constants.d.ts +17 -0
  208. package/dist/types/metrics/index.d.ts +4 -111
  209. package/dist/types/multistream/mediaRequestManager.d.ts +72 -3
  210. package/dist/types/multistream/receiveSlot.d.ts +7 -3
  211. package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
  212. package/dist/types/multistream/remoteMedia.d.ts +3 -31
  213. package/dist/types/multistream/remoteMediaGroup.d.ts +2 -9
  214. package/dist/types/multistream/remoteMediaManager.d.ts +62 -2
  215. package/dist/types/multistream/sendSlotManager.d.ts +70 -0
  216. package/dist/types/reachability/clusterReachability.d.ts +109 -0
  217. package/dist/types/reachability/index.d.ts +60 -95
  218. package/dist/types/reachability/request.d.ts +3 -1
  219. package/dist/types/reachability/util.d.ts +8 -0
  220. package/dist/types/reconnection-manager/index.d.ts +19 -0
  221. package/dist/types/recording-controller/index.d.ts +15 -1
  222. package/dist/types/recording-controller/util.d.ts +5 -4
  223. package/dist/types/roap/index.d.ts +2 -1
  224. package/dist/types/roap/request.d.ts +9 -8
  225. package/dist/types/roap/turnDiscovery.d.ts +39 -5
  226. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  227. package/dist/types/rtcMetrics/index.d.ts +61 -0
  228. package/dist/types/statsAnalyzer/index.d.ts +34 -12
  229. package/dist/types/statsAnalyzer/mqaUtil.d.ts +28 -4
  230. package/dist/types/webinar/collection.d.ts +16 -0
  231. package/dist/types/webinar/index.d.ts +5 -0
  232. package/dist/webinar/collection.js +44 -0
  233. package/dist/webinar/collection.js.map +1 -0
  234. package/dist/webinar/index.js +69 -0
  235. package/dist/webinar/index.js.map +1 -0
  236. package/package.json +22 -19
  237. package/src/annotation/annotation.types.ts +50 -0
  238. package/src/annotation/constants.ts +36 -0
  239. package/src/annotation/index.ts +328 -0
  240. package/src/breakouts/README.md +35 -11
  241. package/src/breakouts/breakout.ts +67 -9
  242. package/src/breakouts/events.ts +56 -0
  243. package/src/breakouts/index.ts +558 -59
  244. package/src/breakouts/utils.ts +42 -0
  245. package/src/common/errors/no-meeting-info.ts +24 -0
  246. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  247. package/src/common/errors/webex-errors.ts +44 -2
  248. package/src/common/logs/logger-proxy.ts +1 -1
  249. package/src/common/logs/request.ts +5 -1
  250. package/src/common/queue.ts +22 -8
  251. package/src/config.ts +4 -9
  252. package/src/constants.ts +229 -21
  253. package/src/controls-options-manager/enums.ts +12 -0
  254. package/src/controls-options-manager/index.ts +116 -21
  255. package/src/controls-options-manager/types.ts +59 -0
  256. package/src/controls-options-manager/util.ts +294 -14
  257. package/src/index.ts +44 -0
  258. package/src/interceptors/index.ts +3 -0
  259. package/src/interceptors/locusRetry.ts +67 -0
  260. package/src/interpretation/README.md +60 -0
  261. package/src/interpretation/collection.ts +19 -0
  262. package/src/interpretation/index.ts +349 -0
  263. package/src/interpretation/siLanguage.ts +18 -0
  264. package/src/locus-info/controlsUtils.ts +108 -0
  265. package/src/locus-info/index.ts +417 -59
  266. package/src/locus-info/infoUtils.ts +10 -2
  267. package/src/locus-info/mediaSharesUtils.ts +80 -0
  268. package/src/locus-info/parser.ts +258 -47
  269. package/src/locus-info/selfUtils.ts +81 -5
  270. package/src/media/index.ts +100 -108
  271. package/src/media/properties.ts +88 -117
  272. package/src/mediaQualityMetrics/config.ts +103 -238
  273. package/src/meeting/in-meeting-actions.ts +171 -3
  274. package/src/meeting/index.ts +3411 -2435
  275. package/src/meeting/locusMediaRequest.ts +313 -0
  276. package/src/meeting/muteState.ts +223 -136
  277. package/src/meeting/request.ts +155 -120
  278. package/src/meeting/util.ts +685 -395
  279. package/src/meeting-info/index.ts +81 -8
  280. package/src/meeting-info/meeting-info-v2.ts +170 -14
  281. package/src/meeting-info/util.ts +1 -1
  282. package/src/meeting-info/utilv2.ts +23 -23
  283. package/src/meetings/collection.ts +33 -0
  284. package/src/meetings/index.ts +507 -127
  285. package/src/meetings/meetings.types.ts +12 -0
  286. package/src/meetings/request.ts +2 -0
  287. package/src/meetings/util.ts +81 -12
  288. package/src/member/index.ts +58 -0
  289. package/src/member/types.ts +38 -0
  290. package/src/member/util.ts +141 -25
  291. package/src/members/collection.ts +8 -0
  292. package/src/members/index.ts +134 -8
  293. package/src/members/request.ts +97 -17
  294. package/src/members/types.ts +29 -0
  295. package/src/members/util.ts +333 -240
  296. package/src/metrics/constants.ts +17 -0
  297. package/src/metrics/index.ts +1 -469
  298. package/src/multistream/mediaRequestManager.ts +271 -56
  299. package/src/multistream/receiveSlot.ts +11 -4
  300. package/src/multistream/receiveSlotManager.ts +34 -24
  301. package/src/multistream/remoteMedia.ts +5 -3
  302. package/src/multistream/remoteMediaGroup.ts +78 -0
  303. package/src/multistream/remoteMediaManager.ts +248 -44
  304. package/src/multistream/sendSlotManager.ts +199 -0
  305. package/src/reachability/clusterReachability.ts +320 -0
  306. package/src/reachability/index.ts +229 -346
  307. package/src/reachability/request.ts +8 -4
  308. package/src/reachability/util.ts +24 -0
  309. package/src/reconnection-manager/index.ts +128 -97
  310. package/src/recording-controller/index.ts +20 -3
  311. package/src/recording-controller/util.ts +26 -9
  312. package/src/roap/index.ts +52 -23
  313. package/src/roap/request.ts +48 -67
  314. package/src/roap/turnDiscovery.ts +147 -49
  315. package/src/rtcMetrics/constants.ts +3 -0
  316. package/src/rtcMetrics/index.ts +166 -0
  317. package/src/statsAnalyzer/index.ts +457 -416
  318. package/src/statsAnalyzer/mqaUtil.ts +317 -170
  319. package/src/webinar/collection.ts +31 -0
  320. package/src/webinar/index.ts +62 -0
  321. package/test/integration/spec/converged-space-meetings.js +60 -3
  322. package/test/integration/spec/journey.js +320 -261
  323. package/test/integration/spec/space-meeting.js +76 -3
  324. package/test/unit/spec/annotation/index.ts +418 -0
  325. package/test/unit/spec/breakouts/breakout.ts +118 -28
  326. package/test/unit/spec/breakouts/events.ts +89 -0
  327. package/test/unit/spec/breakouts/index.ts +1349 -114
  328. package/test/unit/spec/breakouts/utils.js +52 -1
  329. package/test/unit/spec/common/queue.js +31 -2
  330. package/test/unit/spec/controls-options-manager/index.js +163 -0
  331. package/test/unit/spec/controls-options-manager/util.js +576 -60
  332. package/test/unit/spec/fixture/locus.js +1 -0
  333. package/test/unit/spec/interceptors/locusRetry.ts +131 -0
  334. package/test/unit/spec/interpretation/collection.ts +15 -0
  335. package/test/unit/spec/interpretation/index.ts +625 -0
  336. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  337. package/test/unit/spec/locus-info/controlsUtils.js +316 -43
  338. package/test/unit/spec/locus-info/index.js +1363 -37
  339. package/test/unit/spec/locus-info/infoUtils.js +37 -15
  340. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  341. package/test/unit/spec/locus-info/mediaSharesUtils.ts +41 -0
  342. package/test/unit/spec/locus-info/parser.js +116 -35
  343. package/test/unit/spec/locus-info/selfConstant.js +27 -4
  344. package/test/unit/spec/locus-info/selfUtils.js +208 -17
  345. package/test/unit/spec/media/index.ts +173 -81
  346. package/test/unit/spec/media/properties.ts +2 -2
  347. package/test/unit/spec/meeting/in-meeting-actions.ts +85 -3
  348. package/test/unit/spec/meeting/index.js +6821 -2172
  349. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  350. package/test/unit/spec/meeting/muteState.js +402 -212
  351. package/test/unit/spec/meeting/request.js +473 -54
  352. package/test/unit/spec/meeting/utils.js +773 -67
  353. package/test/unit/spec/meeting-info/index.js +300 -0
  354. package/test/unit/spec/meeting-info/meetinginfov2.js +526 -5
  355. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  356. package/test/unit/spec/meetings/collection.js +26 -0
  357. package/test/unit/spec/meetings/index.js +1415 -213
  358. package/test/unit/spec/meetings/utils.js +229 -2
  359. package/test/unit/spec/member/index.js +61 -6
  360. package/test/unit/spec/member/util.js +510 -34
  361. package/test/unit/spec/members/index.js +432 -1
  362. package/test/unit/spec/members/request.js +206 -27
  363. package/test/unit/spec/members/utils.js +210 -0
  364. package/test/unit/spec/metrics/index.js +1 -50
  365. package/test/unit/spec/multistream/mediaRequestManager.ts +781 -114
  366. package/test/unit/spec/multistream/receiveSlot.ts +9 -1
  367. package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
  368. package/test/unit/spec/multistream/remoteMedia.ts +2 -0
  369. package/test/unit/spec/multistream/remoteMediaGroup.ts +345 -0
  370. package/test/unit/spec/multistream/remoteMediaManager.ts +525 -0
  371. package/test/unit/spec/multistream/sendSlotManager.ts +274 -0
  372. package/test/unit/spec/reachability/clusterReachability.ts +279 -0
  373. package/test/unit/spec/reachability/index.ts +551 -14
  374. package/test/unit/spec/reachability/request.js +3 -1
  375. package/test/unit/spec/reachability/util.ts +40 -0
  376. package/test/unit/spec/reconnection-manager/index.js +171 -11
  377. package/test/unit/spec/recording-controller/index.js +294 -218
  378. package/test/unit/spec/recording-controller/util.js +223 -96
  379. package/test/unit/spec/roap/index.ts +180 -83
  380. package/test/unit/spec/roap/request.ts +100 -62
  381. package/test/unit/spec/roap/turnDiscovery.ts +388 -96
  382. package/test/unit/spec/rtcMetrics/index.ts +122 -0
  383. package/test/unit/spec/stats-analyzer/index.js +1252 -12
  384. package/test/unit/spec/webinar/collection.ts +13 -0
  385. package/test/unit/spec/webinar/index.ts +60 -0
  386. package/test/utils/integrationTestUtils.js +46 -0
  387. package/test/utils/testUtils.js +0 -57
  388. package/test/utils/webex-test-users.js +12 -4
  389. package/dist/metrics/config.js +0 -289
  390. package/dist/metrics/config.js.map +0 -1
  391. package/dist/types/metrics/config.d.ts +0 -169
  392. package/src/index.js +0 -18
  393. package/src/metrics/config.ts +0 -485
@@ -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
 
@@ -6,25 +6,16 @@ import {ReceiveSlotManager} from '@webex/plugin-meetings/src/multistream/receive
6
6
  import * as ReceiveSlotModule from '@webex/plugin-meetings/src/multistream/receiveSlot';
7
7
 
8
8
  describe('ReceiveSlotManager', () => {
9
- let fakeMeeting;
10
9
  let fakeWcmeSlot;
11
10
  let fakeReceiveSlots;
12
11
  let mockReceiveSlotCtor;
13
12
  let receiveSlotManager;
13
+ let createSlotCallbackStub;
14
+ let findMemberIdCallbackStub;
14
15
 
15
16
  beforeEach(() => {
16
17
  fakeWcmeSlot = {
17
- id: 'fake wcme slot',
18
- };
19
- fakeMeeting = {
20
- mediaProperties: {
21
- webrtcMediaConnection: {
22
- createReceiveSlot: sinon.stub().resolves(fakeWcmeSlot),
23
- },
24
- },
25
- members: {
26
- findMemberByCsi: sinon.stub(),
27
- },
18
+ id: {ssrc: 1},
28
19
  };
29
20
  fakeReceiveSlots = [];
30
21
  mockReceiveSlotCtor = sinon.stub(ReceiveSlotModule, 'ReceiveSlot').callsFake((mediaType) => {
@@ -32,6 +23,7 @@ describe('ReceiveSlotManager', () => {
32
23
  id: `fake sdk receive slot ${fakeReceiveSlots.length + 1}`,
33
24
  mediaType,
34
25
  findMemberId: sinon.stub(),
26
+ wcmeReceiveSlot: fakeWcmeSlot,
35
27
  };
36
28
 
37
29
  fakeReceiveSlots.push(fakeReceiveSlot);
@@ -39,7 +31,10 @@ describe('ReceiveSlotManager', () => {
39
31
  return fakeReceiveSlot;
40
32
  });
41
33
 
42
- receiveSlotManager = new ReceiveSlotManager(fakeMeeting);
34
+ createSlotCallbackStub = sinon.stub().resolves(fakeWcmeSlot);
35
+ findMemberIdCallbackStub = sinon.stub();
36
+
37
+ receiveSlotManager = new ReceiveSlotManager(createSlotCallbackStub, findMemberIdCallbackStub);
43
38
  });
44
39
 
45
40
  afterEach(() => {
@@ -47,7 +42,7 @@ describe('ReceiveSlotManager', () => {
47
42
  });
48
43
 
49
44
  it('rejects if there is no media connection', async () => {
50
- fakeMeeting.mediaProperties.webrtcMediaConnection = null;
45
+ createSlotCallbackStub.rejects(new Error('Webrtc media connection is missing'));
51
46
 
52
47
  assert.isRejected(
53
48
  receiveSlotManager.allocateSlot(MediaType.VideoMain),
@@ -60,14 +55,14 @@ describe('ReceiveSlotManager', () => {
60
55
 
61
56
  const slot = await receiveSlotManager.allocateSlot(MediaType.VideoMain);
62
57
 
63
- assert.calledOnce(fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot);
58
+ assert.calledOnce(createSlotCallbackStub);
64
59
  assert.calledWith(
65
- fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot,
60
+ createSlotCallbackStub,
66
61
  MediaType.VideoMain
67
62
  );
68
63
 
69
64
  assert.calledOnce(mockReceiveSlotCtor);
70
- assert.calledWith(mockReceiveSlotCtor, MediaType.VideoMain, fakeWcmeSlot, sinon.match.func);
65
+ assert.calledWith(mockReceiveSlotCtor, MediaType.VideoMain, fakeWcmeSlot, findMemberIdCallbackStub);
71
66
  assert.strictEqual(slot, fakeReceiveSlots[0]);
72
67
 
73
68
  assert.deepEqual(receiveSlotManager.getStats(), {
@@ -79,7 +74,7 @@ describe('ReceiveSlotManager', () => {
79
74
  it('reuses previously freed slot when allocateSlot() is called and a free slot is available', async () => {
80
75
  const slot1 = await receiveSlotManager.allocateSlot(MediaType.VideoMain);
81
76
 
82
- assert.calledOnce(fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot);
77
+ assert.calledOnce(createSlotCallbackStub);
83
78
  assert.calledOnce(mockReceiveSlotCtor);
84
79
  assert.strictEqual(slot1, fakeReceiveSlots[0]);
85
80
 
@@ -91,13 +86,13 @@ describe('ReceiveSlotManager', () => {
91
86
  numFreeSlots: {'VIDEO-MAIN': 1},
92
87
  });
93
88
 
94
- fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot.resetHistory();
89
+ createSlotCallbackStub.resetHistory();
95
90
  mockReceiveSlotCtor.resetHistory();
96
91
 
97
92
  // allocate another slot, this time the previous one should be returned instead of allocating any new ones
98
93
  const slot2 = await receiveSlotManager.allocateSlot(MediaType.VideoMain);
99
94
 
100
- assert.notCalled(fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot);
95
+ assert.notCalled(createSlotCallbackStub);
101
96
  assert.notCalled(mockReceiveSlotCtor);
102
97
 
103
98
  // verify that in fact we got the same slot again
@@ -112,7 +107,7 @@ describe('ReceiveSlotManager', () => {
112
107
  it('does not reuse any slots after reset() is called', async () => {
113
108
  const slot1 = await receiveSlotManager.allocateSlot(MediaType.VideoMain);
114
109
 
115
- assert.calledOnce(fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot);
110
+ assert.calledOnce(createSlotCallbackStub);
116
111
  assert.calledOnce(mockReceiveSlotCtor);
117
112
  assert.strictEqual(slot1, fakeReceiveSlots[0]);
118
113
 
@@ -121,7 +116,7 @@ describe('ReceiveSlotManager', () => {
121
116
  receiveSlotManager.reset();
122
117
 
123
118
  // reset the mocks and set the ReceiveSlot constructor to return a different slot
124
- fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot.resetHistory();
119
+ createSlotCallbackStub.resetHistory();
125
120
  mockReceiveSlotCtor.resetHistory();
126
121
 
127
122
  assert.deepEqual(receiveSlotManager.getStats(), {numAllocatedSlots: {}, numFreeSlots: {}});
@@ -129,7 +124,7 @@ describe('ReceiveSlotManager', () => {
129
124
  // allocate another slot, because we called reset(), the old free slot should not be reused
130
125
  const slot2 = await receiveSlotManager.allocateSlot(MediaType.VideoMain);
131
126
 
132
- assert.calledOnce(fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot);
127
+ assert.calledOnce(createSlotCallbackStub);
133
128
  assert.calledOnce(mockReceiveSlotCtor);
134
129
 
135
130
  // verify that in fact we got a brand new slot
@@ -144,25 +139,25 @@ describe('ReceiveSlotManager', () => {
144
139
  it('does not reuse slots if they have different media type', async () => {
145
140
  const slot1 = await receiveSlotManager.allocateSlot(MediaType.VideoMain);
146
141
 
147
- assert.calledOnce(fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot);
142
+ assert.calledOnce(createSlotCallbackStub);
148
143
  assert.calledOnce(mockReceiveSlotCtor);
149
144
 
150
145
  receiveSlotManager.releaseSlot(slot1);
151
146
 
152
- fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot.resetHistory();
147
+ createSlotCallbackStub.resetHistory();
153
148
  mockReceiveSlotCtor.resetHistory();
154
149
 
155
150
  // allocate another slot, this time for main audio, so it should be a completely new slot
156
151
  const slot2 = await receiveSlotManager.allocateSlot(MediaType.AudioMain);
157
152
 
158
- assert.calledOnce(fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot);
153
+ assert.calledOnce(createSlotCallbackStub);
159
154
  assert.calledWith(
160
- fakeMeeting.mediaProperties.webrtcMediaConnection.createReceiveSlot,
155
+ createSlotCallbackStub,
161
156
  MediaType.AudioMain
162
157
  );
163
158
 
164
159
  assert.calledOnce(mockReceiveSlotCtor);
165
- assert.calledWith(mockReceiveSlotCtor, MediaType.AudioMain, fakeWcmeSlot, sinon.match.func);
160
+ assert.calledWith(mockReceiveSlotCtor, MediaType.AudioMain, fakeWcmeSlot, findMemberIdCallbackStub);
166
161
 
167
162
  // verify that in fact we got a brand new slot
168
163
  assert.strictEqual(slot2, fakeReceiveSlots[1]);
@@ -174,7 +169,6 @@ describe('ReceiveSlotManager', () => {
174
169
  });
175
170
 
176
171
  describe('updateMemberIds', () => {
177
-
178
172
  it('calls findMemberId() on all allocated receive slots', async () => {
179
173
  const audioSlots: ReceiveSlot[] = [];
180
174
  const videoSlots: ReceiveSlot[] = [];
@@ -193,9 +187,17 @@ describe('ReceiveSlotManager', () => {
193
187
 
194
188
  assert.strictEqual(fakeReceiveSlots.length, audioSlots.length + videoSlots.length);
195
189
 
196
- fakeReceiveSlots.forEach(slot => {
190
+ fakeReceiveSlots.forEach((slot) => {
197
191
  assert.calledOnce(slot.findMemberId);
198
192
  });
199
193
  });
200
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
+ });
201
203
  });
@@ -240,6 +240,8 @@ describe('RemoteMedia', () => {
240
240
  {height: 270, fs: 920},
241
241
  {height: 539, fs: 920},
242
242
  {height: 540, fs: 3600},
243
+ {height: 720, fs: 3600},
244
+ {height: 721, fs: 8192},
243
245
  ],
244
246
  ({height, fs}) => {
245
247
  it(`sets the max fs to ${fs} correctly when height is ${height}`, () => {
@@ -6,6 +6,7 @@ import {RemoteMedia} from '@webex/plugin-meetings/src/multistream/remoteMedia';
6
6
  import {ReceiveSlot} from '@webex/plugin-meetings/src/multistream/receiveSlot';
7
7
  import sinon from 'sinon';
8
8
  import {assert} from '@webex/test-helper-chai';
9
+ import { NamedMediaGroup } from "@webex/json-multistream";
9
10
 
10
11
  class FakeSlot extends EventEmitter {
11
12
  public mediaType: MediaType;
@@ -24,6 +25,7 @@ describe('RemoteMediaGroup', () => {
24
25
 
25
26
  let fakeMediaRequestManager;
26
27
  let fakeReceiveSlots;
28
+ let fakeNamedMediaSlots;
27
29
 
28
30
  let activeSpeakerRequestCounter;
29
31
  let receiverSelectedRequestCounter;
@@ -50,6 +52,10 @@ describe('RemoteMediaGroup', () => {
50
52
  fakeReceiveSlots = Array(NUM_SLOTS)
51
53
  .fill(null)
52
54
  .map((_, index) => new FakeSlot(MediaType.VideoMain, `fake receive slot ${index}`));
55
+
56
+ fakeNamedMediaSlots = Array(1)
57
+ .fill(null)
58
+ .map((_, index) => new FakeSlot(MediaType.AudioMain, `fake named media receive slot ${index}`));
53
59
  });
54
60
 
55
61
  const getLastActiveSpeakerRequestId = () =>
@@ -97,6 +103,345 @@ describe('RemoteMediaGroup', () => {
97
103
  });
98
104
  });
99
105
 
106
+ describe('setPreferLiveVideo', () => {
107
+ it('updates prefer live video', () => {
108
+
109
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
110
+ resolution: 'medium',
111
+ preferLiveVideo: false,
112
+ });
113
+ fakeMediaRequestManager.addRequest.resetHistory();
114
+ group.setPreferLiveVideo(true, false);
115
+
116
+ assert.calledOnce(fakeMediaRequestManager.cancelRequest);
117
+
118
+ assert.calledOnce(fakeMediaRequestManager.addRequest);
119
+
120
+ assert.calledWith(
121
+ fakeMediaRequestManager.addRequest,
122
+ sinon.match({
123
+ policyInfo: sinon.match({
124
+ policy: 'active-speaker',
125
+ priority: 255,
126
+ preferLiveVideo: true
127
+ }),
128
+ receiveSlots: fakeReceiveSlots,
129
+ codecInfo: sinon.match({
130
+ codec: 'h264',
131
+ maxFs: 3600,
132
+ }),
133
+ }),
134
+ false,
135
+ );
136
+ });
137
+
138
+ it('does not call add request when prefer live video has not changed', () => {
139
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
140
+ resolution: 'medium',
141
+ preferLiveVideo: true,
142
+ });
143
+ fakeMediaRequestManager.addRequest.resetHistory();
144
+ group.setPreferLiveVideo(true, false);
145
+
146
+ assert.notCalled(fakeMediaRequestManager.cancelRequest);
147
+
148
+ assert.notCalled(fakeMediaRequestManager.addRequest);
149
+ });
150
+
151
+ });
152
+
153
+ describe('setNamedMediaGroup', () => {
154
+ it('updates named media group', () => {
155
+
156
+ const nameGroup1 = { type: 1, value: 20 };
157
+ const nameGroup2 = { type: 1, value: 24 };
158
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeNamedMediaSlots, 255, true, {
159
+ namedMediaGroup: nameGroup1,
160
+ });
161
+ fakeMediaRequestManager.addRequest.resetHistory();
162
+ group.setNamedMediaGroup(nameGroup2, false);
163
+
164
+ assert.calledOnce(fakeMediaRequestManager.cancelRequest);
165
+
166
+ assert.calledOnce(fakeMediaRequestManager.addRequest);
167
+
168
+ assert.calledWith(
169
+ fakeMediaRequestManager.addRequest,
170
+ sinon.match({
171
+ policyInfo: sinon.match({
172
+ policy: 'active-speaker',
173
+ priority: 255,
174
+ namedMediaGroups: sinon.match([{type: 1, value: 24}]),
175
+ }),
176
+ receiveSlots: fakeNamedMediaSlots,
177
+ codecInfo: undefined,
178
+ }),
179
+ false,
180
+ );
181
+ });
182
+
183
+ it('does not call add request when named media group has not changed', () => {
184
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeNamedMediaSlots, 255, true, {
185
+ namedMediaGroup: { type: 1, value: 20 },
186
+ });
187
+ fakeMediaRequestManager.addRequest.resetHistory();
188
+ group.setNamedMediaGroup({ type: 1, value: 20 }, false);
189
+
190
+ assert.notCalled(fakeMediaRequestManager.cancelRequest);
191
+
192
+ assert.notCalled(fakeMediaRequestManager.addRequest);
193
+ });
194
+
195
+ it('remove named media group', () => {
196
+
197
+ const nameGroup1 = { type: 1, value: 20 };
198
+ const nameGroup2 = { type: 1, value: 0 };
199
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeNamedMediaSlots, 255, true, {
200
+ namedMediaGroup: nameGroup1,
201
+ });
202
+ fakeMediaRequestManager.addRequest.resetHistory();
203
+ group.setNamedMediaGroup(nameGroup2, true);
204
+
205
+ assert.calledOnce(fakeMediaRequestManager.cancelRequest);
206
+
207
+ assert.calledOnce(fakeMediaRequestManager.addRequest);
208
+
209
+ assert.calledWith(
210
+ fakeMediaRequestManager.addRequest,
211
+ sinon.match({
212
+ policyInfo: sinon.match({
213
+ policy: 'active-speaker',
214
+ priority: 255,
215
+ nameMediaGroups: undefined,
216
+ }),
217
+ receiveSlots: fakeNamedMediaSlots,
218
+ codecInfo: undefined,
219
+ }),
220
+ true,
221
+ );
222
+ });
223
+
224
+ });
225
+
226
+ describe('setActiveSpeakerCsis', () => {
227
+ it('checks when there is a csi and remote media is not in pinned array', () => {
228
+ const PINNED_INDEX = 2;
229
+ const CSI = 11111;
230
+
231
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
232
+ resolution: 'medium',
233
+ preferLiveVideo: true,
234
+ });
235
+
236
+ // initially nothing should be pinned
237
+ assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS); // by default should return 'all'
238
+ assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
239
+ assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS);
240
+ assert.strictEqual(group.getRemoteMedia('pinned').length, 0);
241
+
242
+ const remoteMedia = group.getRemoteMedia('all')[PINNED_INDEX];
243
+
244
+ resetHistory();
245
+
246
+ group.setActiveSpeakerCsis([{remoteMedia, csi: CSI}], 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
+ // now check that correct media requests were sent...
255
+
256
+ const expectedReceiverSelectedSlots = [fakeReceiveSlots[PINNED_INDEX]];
257
+ const expectedActiveSpeakerReceiveSlots = fakeReceiveSlots.filter(
258
+ (_, idx) => idx !== PINNED_INDEX
259
+ );
260
+
261
+ // the previous active speaker media request for the group should have been cancelled
262
+ assert.calledOnce(fakeMediaRequestManager.cancelRequest);
263
+ assert.calledWith(fakeMediaRequestManager.cancelRequest, 'fake active speaker request 1');
264
+ // a new one should be sent for active speaker and for receiver selected
265
+ assert.calledTwice(fakeMediaRequestManager.addRequest);
266
+ assert.calledWith(
267
+ fakeMediaRequestManager.addRequest,
268
+ sinon.match({
269
+ policyInfo: sinon.match({
270
+ policy: 'active-speaker',
271
+ priority: 255,
272
+ }),
273
+ receiveSlots: expectedActiveSpeakerReceiveSlots,
274
+ codecInfo: sinon.match({
275
+ codec: 'h264',
276
+ maxFs: 3600,
277
+ }),
278
+ })
279
+ );
280
+ assert.calledWith(
281
+ fakeMediaRequestManager.addRequest,
282
+ sinon.match({
283
+ policyInfo: sinon.match({
284
+ policy: 'receiver-selected',
285
+ csi: CSI,
286
+ }),
287
+ receiveSlots: expectedReceiverSelectedSlots,
288
+ codecInfo: sinon.match({
289
+ codec: 'h264',
290
+ maxFs: 3600,
291
+ }),
292
+ })
293
+ );
294
+ assert.notCalled(fakeMediaRequestManager.commit);
295
+ });
296
+
297
+ it('checks when there is csi and remoteMedia is in pinned array', () => {
298
+ const PINNED_INDEX = 4;
299
+
300
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
301
+ resolution: 'medium',
302
+ preferLiveVideo: true,
303
+ });
304
+
305
+ // take one instance of remote media from the group
306
+ const remoteMedia = group.getRemoteMedia('all')[PINNED_INDEX];
307
+
308
+ resetHistory();
309
+
310
+ // pin it so that it is in pinned array
311
+ group.setActiveSpeakerCsis([{remoteMedia, csi: 1234}], false);
312
+
313
+ assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS); // by default should return 'all'
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
+
318
+ resetHistory();
319
+ // normally this would result in the underlying receive slot csi to be updated, because we're using fake
320
+ // receive slots, we have to do that manually:
321
+ fakeReceiveSlots[PINNED_INDEX].csi = 1234;
322
+ const expectedReceiverSelectedSlots = [fakeReceiveSlots[PINNED_INDEX]];
323
+
324
+ // pin again to same CSI
325
+ group.setActiveSpeakerCsis([{remoteMedia, csi: 1234}], false);
326
+
327
+ assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS); // by default should return 'all'
328
+ assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
329
+ assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS - 1);
330
+ assert.strictEqual(group.getRemoteMedia('pinned').length, 1);
331
+
332
+ assert.strictEqual(group.isPinned(remoteMedia), true);
333
+
334
+ assert.calledTwice(fakeMediaRequestManager.cancelRequest);
335
+ assert.calledWith(fakeMediaRequestManager.cancelRequest, 'fake receiver selected request 1');
336
+
337
+ assert.calledWith(
338
+ fakeMediaRequestManager.addRequest,
339
+ sinon.match({
340
+ policyInfo: sinon.match({
341
+ policy: 'receiver-selected',
342
+ csi: 1234,
343
+ }),
344
+ receiveSlots: expectedReceiverSelectedSlots,
345
+ codecInfo: sinon.match({
346
+ codec: 'h264',
347
+ maxFs: 3600,
348
+ }),
349
+ })
350
+ );
351
+ assert.notCalled(fakeMediaRequestManager.commit);
352
+ });
353
+
354
+ it('checks setActiveSpeakerCsis with array of remoteMedia to pin and unpin', () => {
355
+ const PINNED_INDEX = 2;
356
+ const PINNED_INDEX2 = 0;
357
+ const CSI = 11111;
358
+ const CSI2 = 12345;
359
+
360
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
361
+ resolution: 'medium',
362
+ preferLiveVideo: true,
363
+ });
364
+
365
+ // initially nothing should be pinned
366
+ assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS); // by default should return 'all'
367
+ assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
368
+ assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS);
369
+ assert.strictEqual(group.getRemoteMedia('pinned').length, 0);
370
+
371
+ const remoteMedia = group.getRemoteMedia('all')[PINNED_INDEX];
372
+
373
+ const remoteMedia2 = group.getRemoteMedia('all')[PINNED_INDEX2];
374
+
375
+ const remoteMedisCsis = [{remoteMedia, csi: CSI}, {remoteMedia: remoteMedia2, csi: CSI2}];
376
+
377
+ group.setActiveSpeakerCsis(remoteMedisCsis, false);
378
+
379
+ assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS);
380
+ assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
381
+ assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS - 2);
382
+ assert.strictEqual(group.getRemoteMedia('pinned').length, 2);
383
+
384
+ assert.strictEqual(group.isPinned(remoteMedia), true);
385
+ assert.strictEqual(group.isPinned(remoteMedia2), true);
386
+
387
+ resetHistory();
388
+
389
+ group.setActiveSpeakerCsis([{remoteMedia}], false);
390
+
391
+ // one pane should still remain pinned
392
+ assert.strictEqual(group.getRemoteMedia().length, NUM_SLOTS);
393
+ assert.strictEqual(group.getRemoteMedia('all').length, NUM_SLOTS);
394
+ assert.strictEqual(group.getRemoteMedia('unpinned').length, NUM_SLOTS - 1);
395
+ assert.strictEqual(group.getRemoteMedia('pinned').length, 1);
396
+ assert.strictEqual(group.isPinned(remoteMedia), false);
397
+ assert.strictEqual(group.isPinned(remoteMedia2), true);
398
+
399
+ assert.calledTwice(fakeMediaRequestManager.cancelRequest);
400
+ assert.calledWith(fakeMediaRequestManager.cancelRequest, 'fake receiver selected request 1');
401
+ assert.notCalled(fakeMediaRequestManager.commit);
402
+ });
403
+
404
+ it('check commit is only called once', () => {
405
+ const PINNED_INDEX = 2;
406
+ const PINNED_INDEX2 = 0;
407
+ const CSI = 11111;
408
+ const CSI2 = 12345;
409
+
410
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
411
+ resolution: 'medium',
412
+ preferLiveVideo: true,
413
+ });
414
+
415
+ const remoteMedia = group.getRemoteMedia('all')[PINNED_INDEX];
416
+
417
+ resetHistory();
418
+
419
+ const remoteMedia2 = group.getRemoteMedia('all')[PINNED_INDEX2];
420
+
421
+ const remoteMedisCsis = [{remoteMedia, csi: CSI}, {remoteMedia: remoteMedia2, csi: CSI2}, {remoteMedia}];
422
+
423
+ group.setActiveSpeakerCsis(remoteMedisCsis, true);
424
+
425
+ assert.calledOnce(fakeMediaRequestManager.commit);
426
+ });
427
+
428
+ it('throws when remoteMedia id is not in unpinned and pinned array - csi is there', () => {
429
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
430
+ resolution: 'medium',
431
+ preferLiveVideo: true,
432
+ });
433
+ 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');
434
+ });
435
+
436
+ it('throws when remoteMedia id is not in unpinned and pinned array - csi is not there', () => {
437
+ const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeReceiveSlots, 255, true, {
438
+ resolution: 'medium',
439
+ preferLiveVideo: true,
440
+ });
441
+ 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');
442
+ });
443
+ });
444
+
100
445
  describe('pinning', () => {
101
446
  it('works as expected', () => {
102
447
  const PINNED_INDEX = 2;