@webex/plugin-meetings 2.59.8 → 2.60.0-next.1

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 (528) hide show
  1. package/README.md +46 -8
  2. package/dist/annotation/annotation.types.js +7 -0
  3. package/dist/annotation/annotation.types.js.map +1 -0
  4. package/dist/annotation/constants.js +41 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +357 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +215 -0
  9. package/dist/breakouts/breakout.js.map +1 -0
  10. package/dist/breakouts/collection.js +22 -0
  11. package/dist/breakouts/collection.js.map +1 -0
  12. package/dist/breakouts/edit-lock-error.js +51 -0
  13. package/dist/breakouts/edit-lock-error.js.map +1 -0
  14. package/dist/breakouts/events.js +44 -0
  15. package/dist/breakouts/events.js.map +1 -0
  16. package/dist/breakouts/index.js +1047 -0
  17. package/dist/breakouts/index.js.map +1 -0
  18. package/dist/breakouts/request.js +77 -0
  19. package/dist/breakouts/request.js.map +1 -0
  20. package/dist/breakouts/utils.js +64 -0
  21. package/dist/breakouts/utils.js.map +1 -0
  22. package/dist/common/browser-detection.js +2 -3
  23. package/dist/common/browser-detection.js.map +1 -1
  24. package/dist/common/collection.js +3 -4
  25. package/dist/common/collection.js.map +1 -1
  26. package/dist/common/config.js +1 -2
  27. package/dist/common/config.js.map +1 -1
  28. package/dist/common/errors/captcha-error.js +1 -2
  29. package/dist/common/errors/captcha-error.js.map +1 -1
  30. package/dist/common/errors/intent-to-join.js +1 -2
  31. package/dist/common/errors/intent-to-join.js.map +1 -1
  32. package/dist/common/errors/join-meeting.js +1 -2
  33. package/dist/common/errors/join-meeting.js.map +1 -1
  34. package/dist/common/errors/media.js +1 -2
  35. package/dist/common/errors/media.js.map +1 -1
  36. package/dist/common/errors/no-meeting-info.js +50 -0
  37. package/dist/common/errors/no-meeting-info.js.map +1 -0
  38. package/dist/common/errors/parameter.js +3 -4
  39. package/dist/common/errors/parameter.js.map +1 -1
  40. package/dist/common/errors/password-error.js +1 -2
  41. package/dist/common/errors/password-error.js.map +1 -1
  42. package/dist/common/errors/permission.js +1 -2
  43. package/dist/common/errors/permission.js.map +1 -1
  44. package/dist/common/errors/reclaim-host-role-errors.js +154 -0
  45. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  46. package/dist/common/errors/reconnection-in-progress.js +1 -2
  47. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  48. package/dist/common/errors/reconnection.js +1 -2
  49. package/dist/common/errors/reconnection.js.map +1 -1
  50. package/dist/common/errors/stats.js +1 -2
  51. package/dist/common/errors/stats.js.map +1 -1
  52. package/dist/common/errors/webex-errors.js +48 -28
  53. package/dist/common/errors/webex-errors.js.map +1 -1
  54. package/dist/common/errors/webex-meetings-error.js +1 -2
  55. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  56. package/dist/common/events/events-scope.js +1 -2
  57. package/dist/common/events/events-scope.js.map +1 -1
  58. package/dist/common/events/events.js +1 -2
  59. package/dist/common/events/events.js.map +1 -1
  60. package/dist/common/events/trigger-proxy.js +1 -2
  61. package/dist/common/events/trigger-proxy.js.map +1 -1
  62. package/dist/common/events/util.js +1 -2
  63. package/dist/common/events/util.js.map +1 -1
  64. package/dist/common/logs/logger-config.js +1 -2
  65. package/dist/common/logs/logger-config.js.map +1 -1
  66. package/dist/common/logs/logger-proxy.js +2 -3
  67. package/dist/common/logs/logger-proxy.js.map +1 -1
  68. package/dist/common/logs/request.js +8 -5
  69. package/dist/common/logs/request.js.map +1 -1
  70. package/dist/common/queue.js +22 -9
  71. package/dist/common/queue.js.map +1 -1
  72. package/dist/config.js +8 -11
  73. package/dist/config.js.map +1 -1
  74. package/dist/constants.js +437 -435
  75. package/dist/constants.js.map +1 -1
  76. package/dist/controls-options-manager/constants.js +3 -6
  77. package/dist/controls-options-manager/constants.js.map +1 -1
  78. package/dist/controls-options-manager/enums.js +14 -6
  79. package/dist/controls-options-manager/enums.js.map +1 -1
  80. package/dist/controls-options-manager/index.js +127 -38
  81. package/dist/controls-options-manager/index.js.map +1 -1
  82. package/dist/controls-options-manager/types.js +7 -0
  83. package/dist/controls-options-manager/types.js.map +1 -0
  84. package/dist/controls-options-manager/util.js +309 -19
  85. package/dist/controls-options-manager/util.js.map +1 -1
  86. package/dist/index.js +116 -4
  87. package/dist/index.js.map +1 -1
  88. package/dist/interpretation/collection.js +22 -0
  89. package/dist/interpretation/collection.js.map +1 -0
  90. package/dist/interpretation/index.js +365 -0
  91. package/dist/interpretation/index.js.map +1 -0
  92. package/dist/interpretation/siLanguage.js +24 -0
  93. package/dist/interpretation/siLanguage.js.map +1 -0
  94. package/dist/locus-info/controlsUtils.js +100 -11
  95. package/dist/locus-info/controlsUtils.js.map +1 -1
  96. package/dist/locus-info/embeddedAppsUtils.js +3 -4
  97. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  98. package/dist/locus-info/fullState.js +1 -2
  99. package/dist/locus-info/fullState.js.map +1 -1
  100. package/dist/locus-info/hostUtils.js +1 -2
  101. package/dist/locus-info/hostUtils.js.map +1 -1
  102. package/dist/locus-info/index.js +425 -84
  103. package/dist/locus-info/index.js.map +1 -1
  104. package/dist/locus-info/infoUtils.js +13 -5
  105. package/dist/locus-info/infoUtils.js.map +1 -1
  106. package/dist/locus-info/mediaSharesUtils.js +58 -3
  107. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  108. package/dist/locus-info/parser.js +253 -80
  109. package/dist/locus-info/parser.js.map +1 -1
  110. package/dist/locus-info/selfUtils.js +97 -13
  111. package/dist/locus-info/selfUtils.js.map +1 -1
  112. package/dist/media/index.js +106 -319
  113. package/dist/media/index.js.map +1 -1
  114. package/dist/media/properties.js +96 -153
  115. package/dist/media/properties.js.map +1 -1
  116. package/dist/media/util.js +1 -22
  117. package/dist/media/util.js.map +1 -1
  118. package/dist/mediaQualityMetrics/config.js +498 -493
  119. package/dist/mediaQualityMetrics/config.js.map +1 -1
  120. package/dist/meeting/in-meeting-actions.js +90 -3
  121. package/dist/meeting/in-meeting-actions.js.map +1 -1
  122. package/dist/meeting/index.js +4578 -2973
  123. package/dist/meeting/index.js.map +1 -1
  124. package/dist/meeting/locusMediaRequest.js +291 -0
  125. package/dist/meeting/locusMediaRequest.js.map +1 -0
  126. package/dist/meeting/muteState.js +224 -133
  127. package/dist/meeting/muteState.js.map +1 -1
  128. package/dist/meeting/request.js +297 -199
  129. package/dist/meeting/request.js.map +1 -1
  130. package/dist/meeting/request.type.js +7 -0
  131. package/dist/meeting/request.type.js.map +1 -0
  132. package/dist/meeting/state.js +1 -2
  133. package/dist/meeting/state.js.map +1 -1
  134. package/dist/meeting/util.js +605 -435
  135. package/dist/meeting/util.js.map +1 -1
  136. package/dist/meeting-info/collection.js +3 -4
  137. package/dist/meeting-info/collection.js.map +1 -1
  138. package/dist/meeting-info/index.js +74 -7
  139. package/dist/meeting-info/index.js.map +1 -1
  140. package/dist/meeting-info/meeting-info-v2.js +197 -63
  141. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  142. package/dist/meeting-info/request.js +1 -2
  143. package/dist/meeting-info/request.js.map +1 -1
  144. package/dist/meeting-info/util.js +2 -3
  145. package/dist/meeting-info/util.js.map +1 -1
  146. package/dist/meeting-info/utilv2.js +25 -12
  147. package/dist/meeting-info/utilv2.js.map +1 -1
  148. package/dist/meetings/collection.js +25 -4
  149. package/dist/meetings/collection.js.map +1 -1
  150. package/dist/meetings/index.js +464 -123
  151. package/dist/meetings/index.js.map +1 -1
  152. package/dist/meetings/meetings.types.js +7 -0
  153. package/dist/meetings/meetings.types.js.map +1 -0
  154. package/dist/meetings/request.js +4 -3
  155. package/dist/meetings/request.js.map +1 -1
  156. package/dist/meetings/util.js +107 -6
  157. package/dist/meetings/util.js.map +1 -1
  158. package/dist/member/index.js +54 -2
  159. package/dist/member/index.js.map +1 -1
  160. package/dist/member/member.types.js +3 -4
  161. package/dist/member/member.types.js.map +1 -1
  162. package/dist/member/types.js +23 -0
  163. package/dist/member/types.js.map +1 -0
  164. package/dist/member/util.js +131 -29
  165. package/dist/member/util.js.map +1 -1
  166. package/dist/members/collection.js +11 -2
  167. package/dist/members/collection.js.map +1 -1
  168. package/dist/members/index.js +174 -10
  169. package/dist/members/index.js.map +1 -1
  170. package/dist/members/request.js +108 -41
  171. package/dist/members/request.js.map +1 -1
  172. package/dist/members/types.js +14 -0
  173. package/dist/members/types.js.map +1 -0
  174. package/dist/members/util.js +327 -234
  175. package/dist/members/util.js.map +1 -1
  176. package/dist/metrics/constants.js +14 -9
  177. package/dist/metrics/constants.js.map +1 -1
  178. package/dist/metrics/index.js +4 -452
  179. package/dist/metrics/index.js.map +1 -1
  180. package/dist/multistream/mediaRequestManager.js +344 -0
  181. package/dist/multistream/mediaRequestManager.js.map +1 -0
  182. package/dist/multistream/receiveSlot.js +200 -0
  183. package/dist/multistream/receiveSlot.js.map +1 -0
  184. package/dist/multistream/receiveSlotManager.js +174 -0
  185. package/dist/multistream/receiveSlotManager.js.map +1 -0
  186. package/dist/multistream/remoteMedia.js +268 -0
  187. package/dist/multistream/remoteMedia.js.map +1 -0
  188. package/dist/multistream/remoteMediaGroup.js +267 -0
  189. package/dist/multistream/remoteMediaGroup.js.map +1 -0
  190. package/dist/multistream/remoteMediaManager.js +1211 -0
  191. package/dist/multistream/remoteMediaManager.js.map +1 -0
  192. package/dist/multistream/sendSlotManager.js +236 -0
  193. package/dist/multistream/sendSlotManager.js.map +1 -0
  194. package/dist/networkQualityMonitor/index.js +5 -4
  195. package/dist/networkQualityMonitor/index.js.map +1 -1
  196. package/dist/personal-meeting-room/index.js +2 -3
  197. package/dist/personal-meeting-room/index.js.map +1 -1
  198. package/dist/personal-meeting-room/request.js +2 -3
  199. package/dist/personal-meeting-room/request.js.map +1 -1
  200. package/dist/personal-meeting-room/util.js +1 -2
  201. package/dist/personal-meeting-room/util.js.map +1 -1
  202. package/dist/reachability/index.js +265 -72
  203. package/dist/reachability/index.js.map +1 -1
  204. package/dist/reachability/request.js +18 -10
  205. package/dist/reachability/request.js.map +1 -1
  206. package/dist/reactions/constants.js +12 -0
  207. package/dist/reactions/constants.js.map +1 -0
  208. package/dist/reactions/reactions.js +4 -6
  209. package/dist/reactions/reactions.js.map +1 -1
  210. package/dist/reactions/reactions.type.js +21 -23
  211. package/dist/reactions/reactions.type.js.map +1 -1
  212. package/dist/reconnection-manager/index.js +272 -220
  213. package/dist/reconnection-manager/index.js.map +1 -1
  214. package/dist/recording-controller/enums.js +4 -5
  215. package/dist/recording-controller/enums.js.map +1 -1
  216. package/dist/recording-controller/index.js +57 -46
  217. package/dist/recording-controller/index.js.map +1 -1
  218. package/dist/recording-controller/util.js +10 -10
  219. package/dist/recording-controller/util.js.map +1 -1
  220. package/dist/roap/index.js +101 -235
  221. package/dist/roap/index.js.map +1 -1
  222. package/dist/roap/request.js +126 -180
  223. package/dist/roap/request.js.map +1 -1
  224. package/dist/roap/turnDiscovery.js +115 -105
  225. package/dist/roap/turnDiscovery.js.map +1 -1
  226. package/dist/rtcMetrics/constants.js +11 -0
  227. package/dist/rtcMetrics/constants.js.map +1 -0
  228. package/dist/rtcMetrics/index.js +115 -0
  229. package/dist/rtcMetrics/index.js.map +1 -0
  230. package/dist/statsAnalyzer/global.js +2 -85
  231. package/dist/statsAnalyzer/global.js.map +1 -1
  232. package/dist/statsAnalyzer/index.js +384 -426
  233. package/dist/statsAnalyzer/index.js.map +1 -1
  234. package/dist/statsAnalyzer/mqaUtil.js +114 -80
  235. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  236. package/dist/transcription/index.js +1 -2
  237. package/dist/transcription/index.js.map +1 -1
  238. package/dist/webinar/collection.js +43 -0
  239. package/dist/webinar/collection.js.map +1 -0
  240. package/dist/webinar/index.js +68 -0
  241. package/dist/webinar/index.js.map +1 -0
  242. package/package.json +34 -24
  243. package/src/annotation/annotation.types.ts +50 -0
  244. package/src/annotation/constants.ts +36 -0
  245. package/src/annotation/index.ts +328 -0
  246. package/src/breakouts/README.md +220 -0
  247. package/src/breakouts/breakout.ts +188 -0
  248. package/src/breakouts/collection.ts +19 -0
  249. package/src/breakouts/edit-lock-error.ts +25 -0
  250. package/src/breakouts/events.ts +56 -0
  251. package/src/breakouts/index.ts +925 -0
  252. package/src/breakouts/request.ts +55 -0
  253. package/src/breakouts/utils.ts +57 -0
  254. package/src/common/errors/no-meeting-info.ts +24 -0
  255. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  256. package/src/common/errors/webex-errors.ts +36 -12
  257. package/src/common/logs/logger-proxy.ts +1 -1
  258. package/src/common/logs/request.ts +5 -1
  259. package/src/common/queue.ts +22 -8
  260. package/src/config.ts +5 -7
  261. package/src/constants.ts +263 -91
  262. package/src/controls-options-manager/enums.ts +11 -1
  263. package/src/controls-options-manager/index.ts +116 -21
  264. package/src/controls-options-manager/types.ts +59 -0
  265. package/src/controls-options-manager/util.ts +294 -14
  266. package/src/index.ts +40 -0
  267. package/src/interpretation/README.md +60 -0
  268. package/src/interpretation/collection.ts +19 -0
  269. package/src/interpretation/index.ts +332 -0
  270. package/src/interpretation/siLanguage.ts +18 -0
  271. package/src/locus-info/controlsUtils.ts +110 -0
  272. package/src/locus-info/index.ts +449 -61
  273. package/src/locus-info/infoUtils.ts +14 -2
  274. package/src/locus-info/mediaSharesUtils.ts +64 -0
  275. package/src/locus-info/parser.ts +258 -47
  276. package/src/locus-info/selfUtils.ts +85 -2
  277. package/src/media/index.ts +153 -370
  278. package/src/media/properties.ts +106 -136
  279. package/src/media/util.ts +0 -21
  280. package/src/mediaQualityMetrics/config.ts +379 -377
  281. package/src/meeting/in-meeting-actions.ts +168 -0
  282. package/src/meeting/index.ts +3800 -2491
  283. package/src/meeting/locusMediaRequest.ts +313 -0
  284. package/src/meeting/muteState.ts +224 -138
  285. package/src/meeting/request.ts +207 -127
  286. package/src/meeting/request.type.ts +13 -0
  287. package/src/meeting/util.ts +590 -423
  288. package/src/meeting-info/index.ts +81 -8
  289. package/src/meeting-info/meeting-info-v2.ts +159 -13
  290. package/src/meeting-info/util.ts +1 -1
  291. package/src/meeting-info/utilv2.ts +22 -9
  292. package/src/meetings/collection.ts +20 -0
  293. package/src/meetings/index.ts +466 -124
  294. package/src/meetings/meetings.types.ts +12 -0
  295. package/src/meetings/request.ts +2 -0
  296. package/src/meetings/util.ts +116 -5
  297. package/src/member/index.ts +52 -1
  298. package/src/member/types.ts +38 -0
  299. package/src/member/util.ts +139 -28
  300. package/src/members/collection.ts +8 -0
  301. package/src/members/index.ts +196 -7
  302. package/src/members/request.ts +97 -17
  303. package/src/members/types.ts +29 -0
  304. package/src/members/util.ts +333 -240
  305. package/src/metrics/constants.ts +12 -6
  306. package/src/metrics/index.ts +1 -471
  307. package/src/multistream/mediaRequestManager.ts +440 -0
  308. package/src/multistream/receiveSlot.ts +184 -0
  309. package/src/multistream/receiveSlotManager.ts +166 -0
  310. package/src/multistream/remoteMedia.ts +254 -0
  311. package/src/multistream/remoteMediaGroup.ts +284 -0
  312. package/src/multistream/remoteMediaManager.ts +1145 -0
  313. package/src/multistream/sendSlotManager.ts +170 -0
  314. package/src/networkQualityMonitor/index.ts +6 -6
  315. package/src/reachability/index.ts +238 -45
  316. package/src/reachability/request.ts +17 -8
  317. package/src/reactions/constants.ts +4 -0
  318. package/src/reactions/reactions.ts +4 -4
  319. package/src/reactions/reactions.type.ts +30 -4
  320. package/src/reconnection-manager/index.ts +124 -107
  321. package/src/recording-controller/index.ts +20 -3
  322. package/src/recording-controller/util.ts +26 -9
  323. package/src/roap/index.ts +98 -241
  324. package/src/roap/request.ts +74 -148
  325. package/src/roap/turnDiscovery.ts +62 -56
  326. package/src/rtcMetrics/constants.ts +3 -0
  327. package/src/rtcMetrics/index.ts +100 -0
  328. package/src/statsAnalyzer/global.ts +1 -84
  329. package/src/statsAnalyzer/index.ts +442 -523
  330. package/src/statsAnalyzer/mqaUtil.ts +105 -103
  331. package/src/webinar/collection.ts +31 -0
  332. package/src/webinar/index.ts +62 -0
  333. package/test/integration/spec/converged-space-meetings.js +233 -0
  334. package/test/integration/spec/journey.js +320 -264
  335. package/test/integration/spec/space-meeting.js +77 -4
  336. package/test/unit/spec/annotation/index.ts +418 -0
  337. package/test/unit/spec/breakouts/breakout.ts +237 -0
  338. package/test/unit/spec/breakouts/collection.ts +15 -0
  339. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  340. package/test/unit/spec/breakouts/events.ts +89 -0
  341. package/test/unit/spec/breakouts/index.ts +1790 -0
  342. package/test/unit/spec/breakouts/request.ts +104 -0
  343. package/test/unit/spec/breakouts/utils.js +72 -0
  344. package/test/unit/spec/common/queue.js +31 -2
  345. package/test/unit/spec/controls-options-manager/index.js +163 -0
  346. package/test/unit/spec/controls-options-manager/util.js +576 -60
  347. package/test/unit/spec/fixture/locus.js +1 -0
  348. package/test/unit/spec/interpretation/collection.ts +15 -0
  349. package/test/unit/spec/interpretation/index.ts +589 -0
  350. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  351. package/test/unit/spec/locus-info/controlsUtils.js +323 -30
  352. package/test/unit/spec/locus-info/index.js +1390 -16
  353. package/test/unit/spec/locus-info/infoUtils.js +54 -16
  354. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  355. package/test/unit/spec/locus-info/lib/selfConstant.js +48 -0
  356. package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
  357. package/test/unit/spec/locus-info/parser.js +116 -35
  358. package/test/unit/spec/locus-info/selfUtils.js +275 -0
  359. package/test/unit/spec/media/index.ts +274 -0
  360. package/test/unit/spec/media/properties.ts +75 -84
  361. package/test/unit/spec/meeting/in-meeting-actions.ts +82 -0
  362. package/test/unit/spec/meeting/index.js +7395 -3171
  363. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  364. package/test/unit/spec/meeting/muteState.js +407 -212
  365. package/test/unit/spec/meeting/request.js +512 -42
  366. package/test/unit/spec/meeting/utils.js +741 -24
  367. package/test/unit/spec/meeting-info/index.js +300 -0
  368. package/test/unit/spec/meeting-info/meetinginfov2.js +500 -6
  369. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  370. package/test/unit/spec/meetings/collection.js +14 -0
  371. package/test/unit/spec/meetings/index.js +1012 -209
  372. package/test/unit/spec/meetings/utils.js +202 -2
  373. package/test/unit/spec/member/index.js +38 -8
  374. package/test/unit/spec/member/util.js +528 -27
  375. package/test/unit/spec/members/index.js +597 -3
  376. package/test/unit/spec/members/request.js +206 -27
  377. package/test/unit/spec/members/utils.js +210 -0
  378. package/test/unit/spec/metrics/index.js +1 -50
  379. package/test/unit/spec/multistream/mediaRequestManager.ts +1418 -0
  380. package/test/unit/spec/multistream/receiveSlot.ts +163 -0
  381. package/test/unit/spec/multistream/receiveSlotManager.ts +203 -0
  382. package/test/unit/spec/multistream/remoteMedia.ts +255 -0
  383. package/test/unit/spec/multistream/remoteMediaGroup.ts +662 -0
  384. package/test/unit/spec/multistream/remoteMediaManager.ts +1924 -0
  385. package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
  386. package/test/unit/spec/networkQualityMonitor/index.js +4 -4
  387. package/test/unit/spec/reachability/index.ts +598 -24
  388. package/test/unit/spec/reachability/request.js +68 -0
  389. package/test/unit/spec/reconnection-manager/index.js +130 -22
  390. package/test/unit/spec/recording-controller/index.js +293 -218
  391. package/test/unit/spec/recording-controller/util.js +223 -96
  392. package/test/unit/spec/roap/index.ts +200 -76
  393. package/test/unit/spec/roap/request.ts +232 -0
  394. package/test/unit/spec/roap/turnDiscovery.ts +86 -48
  395. package/test/unit/spec/rtcMetrics/index.ts +73 -0
  396. package/test/unit/spec/stats-analyzer/index.js +181 -177
  397. package/test/unit/spec/webinar/collection.ts +13 -0
  398. package/test/unit/spec/webinar/index.ts +60 -0
  399. package/test/utils/constants.js +9 -0
  400. package/test/utils/integrationTestUtils.js +46 -0
  401. package/test/utils/testUtils.js +0 -45
  402. package/test/utils/webex-config.js +4 -0
  403. package/test/utils/webex-test-users.js +7 -3
  404. package/dist/common/browser-detection.d.ts +0 -9
  405. package/dist/common/collection.d.ts +0 -48
  406. package/dist/common/config.d.ts +0 -2
  407. package/dist/common/errors/captcha-error.d.ts +0 -15
  408. package/dist/common/errors/intent-to-join.d.ts +0 -16
  409. package/dist/common/errors/join-meeting.d.ts +0 -17
  410. package/dist/common/errors/media.d.ts +0 -15
  411. package/dist/common/errors/parameter.d.ts +0 -15
  412. package/dist/common/errors/password-error.d.ts +0 -15
  413. package/dist/common/errors/permission.d.ts +0 -14
  414. package/dist/common/errors/reconnection-in-progress.d.ts +0 -9
  415. package/dist/common/errors/reconnection.d.ts +0 -15
  416. package/dist/common/errors/stats.d.ts +0 -15
  417. package/dist/common/errors/webex-errors.d.ts +0 -81
  418. package/dist/common/errors/webex-meetings-error.d.ts +0 -20
  419. package/dist/common/events/events-scope.d.ts +0 -17
  420. package/dist/common/events/events.d.ts +0 -12
  421. package/dist/common/events/trigger-proxy.d.ts +0 -2
  422. package/dist/common/events/util.d.ts +0 -2
  423. package/dist/common/logs/logger-config.d.ts +0 -2
  424. package/dist/common/logs/logger-proxy.d.ts +0 -2
  425. package/dist/common/logs/request.d.ts +0 -34
  426. package/dist/common/queue.d.ts +0 -32
  427. package/dist/config.d.ts +0 -73
  428. package/dist/constants.d.ts +0 -926
  429. package/dist/controls-options-manager/constants.d.ts +0 -4
  430. package/dist/controls-options-manager/enums.d.ts +0 -5
  431. package/dist/controls-options-manager/index.d.ts +0 -120
  432. package/dist/controls-options-manager/util.d.ts +0 -7
  433. package/dist/index.d.ts +0 -4
  434. package/dist/locus-info/controlsUtils.d.ts +0 -2
  435. package/dist/locus-info/embeddedAppsUtils.d.ts +0 -2
  436. package/dist/locus-info/fullState.d.ts +0 -2
  437. package/dist/locus-info/hostUtils.d.ts +0 -2
  438. package/dist/locus-info/index.d.ts +0 -269
  439. package/dist/locus-info/infoUtils.d.ts +0 -2
  440. package/dist/locus-info/mediaSharesUtils.d.ts +0 -2
  441. package/dist/locus-info/parser.d.ts +0 -212
  442. package/dist/locus-info/selfUtils.d.ts +0 -2
  443. package/dist/media/index.d.ts +0 -32
  444. package/dist/media/properties.d.ts +0 -108
  445. package/dist/media/util.d.ts +0 -2
  446. package/dist/mediaQualityMetrics/config.d.ts +0 -233
  447. package/dist/meeting/effectsState.d.ts +0 -42
  448. package/dist/meeting/effectsState.js +0 -260
  449. package/dist/meeting/effectsState.js.map +0 -1
  450. package/dist/meeting/in-meeting-actions.d.ts +0 -79
  451. package/dist/meeting/index.d.ts +0 -1622
  452. package/dist/meeting/muteState.d.ts +0 -116
  453. package/dist/meeting/request.d.ts +0 -255
  454. package/dist/meeting/state.d.ts +0 -9
  455. package/dist/meeting/util.d.ts +0 -2
  456. package/dist/meeting-info/collection.d.ts +0 -20
  457. package/dist/meeting-info/index.d.ts +0 -57
  458. package/dist/meeting-info/meeting-info-v2.d.ts +0 -93
  459. package/dist/meeting-info/request.d.ts +0 -22
  460. package/dist/meeting-info/util.d.ts +0 -2
  461. package/dist/meeting-info/utilv2.d.ts +0 -2
  462. package/dist/meetings/collection.d.ts +0 -23
  463. package/dist/meetings/index.d.ts +0 -296
  464. package/dist/meetings/request.d.ts +0 -27
  465. package/dist/meetings/util.d.ts +0 -18
  466. package/dist/member/index.d.ts +0 -147
  467. package/dist/member/member.types.d.ts +0 -11
  468. package/dist/member/util.d.ts +0 -2
  469. package/dist/members/collection.d.ts +0 -24
  470. package/dist/members/index.d.ts +0 -298
  471. package/dist/members/request.d.ts +0 -50
  472. package/dist/members/util.d.ts +0 -2
  473. package/dist/metrics/config.d.ts +0 -169
  474. package/dist/metrics/config.js +0 -289
  475. package/dist/metrics/config.js.map +0 -1
  476. package/dist/metrics/constants.d.ts +0 -59
  477. package/dist/metrics/index.d.ts +0 -152
  478. package/dist/networkQualityMonitor/index.d.ts +0 -70
  479. package/dist/peer-connection-manager/index.d.ts +0 -6
  480. package/dist/peer-connection-manager/index.js +0 -671
  481. package/dist/peer-connection-manager/index.js.map +0 -1
  482. package/dist/peer-connection-manager/util.d.ts +0 -6
  483. package/dist/peer-connection-manager/util.js +0 -110
  484. package/dist/peer-connection-manager/util.js.map +0 -1
  485. package/dist/personal-meeting-room/index.d.ts +0 -47
  486. package/dist/personal-meeting-room/request.d.ts +0 -14
  487. package/dist/personal-meeting-room/util.d.ts +0 -2
  488. package/dist/reachability/index.d.ts +0 -139
  489. package/dist/reachability/request.d.ts +0 -35
  490. package/dist/reactions/reactions.d.ts +0 -4
  491. package/dist/reactions/reactions.type.d.ts +0 -32
  492. package/dist/reconnection-manager/index.d.ts +0 -112
  493. package/dist/recording-controller/enums.d.ts +0 -7
  494. package/dist/recording-controller/index.d.ts +0 -193
  495. package/dist/recording-controller/util.d.ts +0 -13
  496. package/dist/roap/collection.d.ts +0 -10
  497. package/dist/roap/collection.js +0 -63
  498. package/dist/roap/collection.js.map +0 -1
  499. package/dist/roap/handler.d.ts +0 -47
  500. package/dist/roap/handler.js +0 -279
  501. package/dist/roap/handler.js.map +0 -1
  502. package/dist/roap/index.d.ts +0 -116
  503. package/dist/roap/request.d.ts +0 -35
  504. package/dist/roap/state.d.ts +0 -9
  505. package/dist/roap/state.js +0 -127
  506. package/dist/roap/state.js.map +0 -1
  507. package/dist/roap/turnDiscovery.d.ts +0 -81
  508. package/dist/roap/util.d.ts +0 -2
  509. package/dist/roap/util.js +0 -76
  510. package/dist/roap/util.js.map +0 -1
  511. package/dist/statsAnalyzer/global.d.ts +0 -118
  512. package/dist/statsAnalyzer/index.d.ts +0 -193
  513. package/dist/statsAnalyzer/mqaUtil.d.ts +0 -22
  514. package/dist/transcription/index.d.ts +0 -64
  515. package/src/index.js +0 -15
  516. package/src/meeting/effectsState.ts +0 -209
  517. package/src/metrics/config.ts +0 -485
  518. package/src/peer-connection-manager/index.ts +0 -847
  519. package/src/peer-connection-manager/util.ts +0 -119
  520. package/src/roap/collection.ts +0 -62
  521. package/src/roap/handler.ts +0 -294
  522. package/src/roap/state.ts +0 -156
  523. package/src/roap/util.ts +0 -100
  524. package/test/unit/spec/meeting/effectsState.js +0 -281
  525. package/test/unit/spec/peerconnection-manager/index.js +0 -218
  526. package/test/unit/spec/peerconnection-manager/utils.js +0 -49
  527. package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -388
  528. package/test/unit/spec/roap/util.js +0 -30
@@ -1,8 +1,7 @@
1
1
  import sinon from 'sinon';
2
2
  import {assert} from '@webex/test-helper-chai';
3
3
  import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
4
- import createMuteState from '@webex/plugin-meetings/src/meeting/muteState';
5
- import Media from '@webex/plugin-meetings/src/media/index';
4
+ import {createMuteState, MuteState} from '@webex/plugin-meetings/src/meeting/muteState';
6
5
  import PermissionError from '@webex/plugin-meetings/src/common/errors/permission';
7
6
  import {AUDIO, VIDEO} from '@webex/plugin-meetings/src/constants';
8
7
 
@@ -12,277 +11,290 @@ describe('plugin-meetings', () => {
12
11
  let meeting;
13
12
  let audio;
14
13
  let video;
14
+ let originalRemoteUpdateAudioVideo;
15
15
 
16
16
  const fakeLocus = {info: 'this is a fake locus'};
17
17
 
18
- beforeEach(() => {
18
+ const createFakeLocalStream = (id, muted) => {
19
+ return {
20
+ id,
21
+ setServerMuted: sinon.stub(),
22
+ setUnmuteAllowed: sinon.stub(),
23
+ setMuted: sinon.stub(),
24
+ muted,
25
+ };
26
+ };
27
+
28
+ beforeEach(async () => {
19
29
  meeting = {
20
30
  mediaProperties: {
21
- audioTrack: 'fake audio track',
22
- videoTrack: 'fake video track',
31
+ audioStream: createFakeLocalStream('fake audio stream', false),
32
+ videoStream: createFakeLocalStream('fake video stream', false),
23
33
  },
24
34
  remoteMuted: false,
25
35
  unmuteAllowed: true,
36
+ remoteVideoMuted: false,
37
+ unmuteVideoAllowed: true,
38
+
26
39
  locusInfo: {
27
- onFullLocus: sinon.stub(),
40
+ handleLocusDelta: sinon.stub(),
28
41
  },
29
42
  members: {
30
43
  selfId: 'fake self id',
31
44
  muteMember: sinon.stub().resolves(),
32
45
  },
33
46
  };
34
- audio = createMuteState(AUDIO, meeting, {sendAudio: true});
35
- video = createMuteState(VIDEO, meeting, {sendVideo: true});
47
+
48
+ originalRemoteUpdateAudioVideo = MeetingUtil.remoteUpdateAudioVideo;
36
49
 
37
50
  MeetingUtil.remoteUpdateAudioVideo = sinon.stub().resolves(fakeLocus);
38
- Media.setLocalTrack = sinon.stub();
39
- });
40
51
 
41
- describe('mute state library', () => {
42
- it('does not create an audio instance if we are not sending audio', async () => {
43
- assert.isNull(createMuteState(AUDIO, meeting, {sendAudio: false}));
44
- assert.isNull(createMuteState(AUDIO, meeting, {}));
45
- });
52
+ audio = createMuteState(AUDIO, meeting, true);
53
+ video = createMuteState(VIDEO, meeting, true);
46
54
 
47
- it('does not create a video instance if we are not sending video', async () => {
48
- assert.isNull(createMuteState(VIDEO, meeting, {sendVideo: false}));
49
- assert.isNull(createMuteState(VIDEO, meeting, {}));
50
- });
55
+ await testUtils.flushPromises();
56
+ });
51
57
 
58
+ afterEach(() => {
59
+ MeetingUtil.remoteUpdateAudioVideo = originalRemoteUpdateAudioVideo;
60
+ });
61
+
62
+ describe('mute state library', () => {
52
63
  it('takes into account current remote mute status when instantiated', async () => {
53
64
  // simulate being already remote muted
54
65
  meeting.remoteMuted = true;
55
- // create a new MuteState intance
56
- audio = createMuteState(AUDIO, meeting, {sendAudio: true});
66
+
67
+ // create a new MuteState instance
68
+ audio = createMuteState(AUDIO, meeting, true);
69
+
70
+ await testUtils.flushPromises();
57
71
 
58
72
  assert.isTrue(audio.isMuted());
59
- assert.isFalse(audio.isSelf());
73
+ assert.isTrue(audio.isRemotelyMuted());
60
74
 
61
75
  // now check the opposite case
62
76
  meeting.remoteMuted = false;
63
77
 
64
- // create a new MuteState intance
65
- audio = createMuteState(AUDIO, meeting, {sendAudio: true});
78
+ // create a new MuteState instance
79
+ audio = createMuteState(AUDIO, meeting, true);
66
80
 
67
- assert.isFalse(audio.isMuted());
68
- assert.isFalse(audio.isSelf());
81
+ await testUtils.flushPromises();
82
+
83
+ assert.isTrue(audio.isMuted()); // because we start with no stream
84
+ assert.isFalse(audio.isRemotelyMuted());
69
85
  });
70
86
 
71
87
  it('initialises correctly for video', async () => {
72
- // setup fields related to audio remote state
73
- meeting.remoteMuted = true;
74
- meeting.unmuteAllowed = false;
75
- // create a new video MuteState intance
76
- video = createMuteState(VIDEO, meeting, {sendVideo: true});
88
+ // setup fields related to video remote state
89
+ meeting.remoteVideoMuted = false;
90
+ meeting.unmuteVideoAllowed = false;
77
91
 
78
- assert.isFalse(video.isMuted());
92
+ // create a new video MuteState instance
93
+ video = createMuteState(VIDEO, meeting, true);
94
+
95
+ await testUtils.flushPromises();
96
+
97
+ assert.isTrue(video.isMuted()); // because we start with no stream
98
+ assert.isFalse(video.isRemotelyMuted());
79
99
  assert.isFalse(video.state.server.remoteMute);
80
- assert.isTrue(video.state.server.unmuteAllowed);
100
+ assert.isFalse(video.state.server.unmuteAllowed);
81
101
  });
82
102
 
83
103
  it('takes remote mute into account when reporting current state', async () => {
84
- assert.isFalse(audio.isMuted());
104
+ assert.isFalse(audio.isRemotelyMuted());
85
105
 
86
106
  // simulate remote mute
87
- audio.handleServerRemoteMuteUpdate(true, true);
107
+ audio.handleServerRemoteMuteUpdate(meeting, true, true);
88
108
 
89
- assert.isTrue(audio.isMuted());
90
- assert.isFalse(audio.isSelf());
109
+ assert.isTrue(audio.isRemotelyMuted());
91
110
  });
92
111
 
93
112
  it('does local unmute if localAudioUnmuteRequired is received', async () => {
94
- // first we need to mute
95
- await audio.handleClientRequest(meeting, true);
113
+ // first we need to mute have the local stream muted
114
+ meeting.mediaProperties.audioStream.muted = true;
115
+ audio.handleLocalStreamChange(meeting);
96
116
 
97
117
  assert.isTrue(audio.isMuted());
98
- assert.isTrue(audio.isSelf());
99
118
 
100
119
  MeetingUtil.remoteUpdateAudioVideo.resetHistory();
101
120
 
102
121
  // now simulate server requiring us to locally unmute
103
122
  audio.handleServerLocalUnmuteRequired(meeting);
123
+
104
124
  await testUtils.flushPromises();
105
125
 
106
- // check that local track was enabled
107
- assert.calledWith(Media.setLocalTrack, true, meeting.mediaProperties.audioTrack);
126
+ // check that local stream was unmuted
127
+ assert.calledWith(
128
+ meeting.mediaProperties.audioStream.setServerMuted,
129
+ false,
130
+ 'localUnmuteRequired'
131
+ );
108
132
 
109
133
  // and local unmute was sent to server
110
134
  assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
111
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, false, undefined, meeting);
135
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, false, undefined);
112
136
 
113
137
  assert.isFalse(audio.isMuted());
114
- assert.isFalse(audio.isSelf());
115
138
  });
116
139
 
117
- it('rejects client request in progress if localAudioUnmuteRequired is received', async () => {
118
- let clientPromiseResolved = false;
119
- let clientPromiseRejected = false;
120
-
121
- // first we need to mute and make that request last forever
122
- let serverResponseResolve;
123
-
124
- MeetingUtil.remoteUpdateAudioVideo = sinon.stub().returns(
125
- new Promise((resolve) => {
126
- serverResponseResolve = resolve;
127
- })
128
- );
140
+ it('does local video unmute if localVideoUnmuteRequired is received', async () => {
141
+ // first we need to mute
142
+ meeting.mediaProperties.videoStream.muted = true;
143
+ video.handleLocalStreamChange(meeting);
129
144
 
130
- audio
131
- .handleClientRequest(meeting, true)
132
- .then(() => {
133
- clientPromiseResolved = true;
134
- })
135
- .catch(() => {
136
- clientPromiseRejected = true;
137
- });
145
+ assert.isTrue(video.isMuted());
138
146
 
139
147
  MeetingUtil.remoteUpdateAudioVideo.resetHistory();
140
148
 
141
149
  // now simulate server requiring us to locally unmute
142
- audio.handleServerLocalUnmuteRequired(meeting);
150
+ video.handleServerLocalUnmuteRequired(meeting);
143
151
  await testUtils.flushPromises();
144
152
 
145
- // the original client request should have been rejected by now
146
- assert.isTrue(clientPromiseRejected);
147
- assert.isFalse(clientPromiseResolved);
148
-
149
- // now make the server respond to the original mute request
150
- serverResponseResolve();
151
- await testUtils.flushPromises();
153
+ // check that local stream was unmuted
154
+ assert.calledWith(
155
+ meeting.mediaProperties.videoStream.setServerMuted,
156
+ false,
157
+ 'localUnmuteRequired'
158
+ );
152
159
 
153
- // local unmute should be sent to server
160
+ // and local unmute was sent to server
154
161
  assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
155
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, false, undefined, meeting);
162
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, false);
156
163
 
157
- // and local track should be enabled
158
- assert.calledWith(Media.setLocalTrack, true, meeting.mediaProperties.audioTrack);
159
-
160
- assert.isFalse(audio.isMuted());
161
- assert.isFalse(audio.isSelf());
164
+ assert.isFalse(video.isMuted());
162
165
  });
163
166
 
164
167
  describe('#isLocallyMuted()', () => {
165
168
  it('does not consider remote mute status for audio', async () => {
166
- // simulate being already remote muted
169
+ // simulate being already remote muted and locally unmuted
167
170
  meeting.remoteMuted = true;
171
+ meeting.mediaProperties.audioStream.muted = false;
168
172
  // create a new MuteState intance
169
- audio = createMuteState(AUDIO, meeting, {sendAudio: true});
173
+ audio = createMuteState(AUDIO, meeting, true);
174
+ audio.handleLocalStreamChange(meeting);
175
+
176
+ await testUtils.flushPromises();
170
177
 
171
178
  assert.isFalse(audio.isLocallyMuted());
172
179
  });
173
- });
174
180
 
175
- describe('#handleClientRequest', () => {
176
- it('disables/enables the local audio track when audio is muted/unmuted', async () => {
177
- // mute
178
- audio.handleClientRequest(meeting, true);
179
- assert.calledWith(Media.setLocalTrack, false, meeting.mediaProperties.audioTrack);
181
+ it('does not consider remote mute status for video', async () => {
182
+ // simulate being already remote muted
183
+ meeting.remoteVideoMuted = true;
184
+ meeting.mediaProperties.videoStream.muted = false;
180
185
 
181
- // even when calling mute when it's already muted should still call setLocalTrack
182
- audio.handleClientRequest(meeting, true);
183
- assert.calledWith(Media.setLocalTrack, false, meeting.mediaProperties.audioTrack);
186
+ // create a new MuteState instance
187
+ video = createMuteState(VIDEO, meeting, true);
188
+ video.handleLocalStreamChange(meeting);
184
189
 
185
- // unmute
186
- audio.handleClientRequest(meeting, false);
187
- assert.calledWith(Media.setLocalTrack, true, meeting.mediaProperties.audioTrack);
190
+ await testUtils.flushPromises();
188
191
 
189
- // even when calling unmute when it's already unmuted should still call setLocalTrack
190
- audio.handleClientRequest(meeting, false);
191
- assert.calledWith(Media.setLocalTrack, true, meeting.mediaProperties.audioTrack);
192
+ assert.isFalse(video.isLocallyMuted());
192
193
  });
194
+ });
193
195
 
194
- it('disables/enables the local video track when video is muted/unmuted', async () => {
195
- // mute
196
- video.handleClientRequest(meeting, true);
197
- assert.calledWith(Media.setLocalTrack, false, meeting.mediaProperties.videoTrack);
196
+ describe('handling local stream mute events', () => {
197
+ beforeEach(async () => {
198
+ audio.handleLocalStreamChange(meeting);
199
+ video.handleLocalStreamChange(meeting);
200
+
201
+ await testUtils.flushPromises();
202
+ });
198
203
 
199
- // even when calling mute when it's already muted should still call setLocalTrack
200
- video.handleClientRequest(meeting, false);
201
- assert.calledWith(Media.setLocalTrack, false, meeting.mediaProperties.videoTrack);
204
+ const simulateAudioMuteChange = async (muteValue) => {
205
+ meeting.mediaProperties.audioStream.muted = muteValue;
206
+ audio.handleLocalStreamMuteStateChange(meeting, muteValue);
202
207
 
203
- // unmute
204
- video.handleClientRequest(meeting, false);
205
- assert.calledWith(Media.setLocalTrack, true, meeting.mediaProperties.videoTrack);
208
+ await testUtils.flushPromises();
209
+ };
206
210
 
207
- // even when calling unmute when it's already unmuted should still call setLocalTrack
208
- video.handleClientRequest(meeting, false);
209
- assert.calledWith(Media.setLocalTrack, true, meeting.mediaProperties.videoTrack);
210
- });
211
+ const simulateVideoMuteChange = async (muteValue) => {
212
+ meeting.mediaProperties.videoStream.muted = muteValue;
213
+ video.handleLocalStreamMuteStateChange(meeting, muteValue);
211
214
 
212
- it('returns correct value in isMuted()/isSelf() methods after client mute/unmute requests', async () => {
213
- // mute
214
- audio.handleClientRequest(meeting, true);
215
+ await testUtils.flushPromises();
216
+ };
215
217
 
218
+ it('returns correct value in isMuted() methods after local stream is muted/unmuted', async () => {
219
+ // mute
220
+ await simulateAudioMuteChange(true);
216
221
  assert.isTrue(audio.isMuted());
217
- assert.isTrue(audio.isSelf());
218
222
 
219
223
  // unmute
220
- audio.handleClientRequest(meeting, false);
221
-
224
+ await simulateAudioMuteChange(false);
222
225
  assert.isFalse(audio.isMuted());
223
- assert.isFalse(audio.isSelf());
224
226
  });
225
227
 
226
228
  it('does remote unmute when unmuting and remote mute is on', async () => {
227
229
  // simulate remote mute
228
- audio.handleServerRemoteMuteUpdate(true, true);
230
+ audio.handleServerRemoteMuteUpdate(meeting, true, true);
229
231
 
230
232
  // unmute
231
- await audio.handleClientRequest(meeting, false);
233
+ await simulateAudioMuteChange(false);
232
234
 
233
235
  // check that remote unmute was sent to server
234
236
  assert.calledOnce(meeting.members.muteMember);
235
- assert.calledWith(meeting.members.muteMember, meeting.members.selfId, false);
237
+ assert.calledWith(meeting.members.muteMember, meeting.members.selfId, false, true);
236
238
 
237
239
  assert.isFalse(audio.isMuted());
238
- assert.isFalse(audio.isSelf());
239
240
  });
240
241
 
241
- it('resolves client request promise once the server is updated', async () => {
242
- let clientPromiseResolved = false;
242
+ it('does video remote unmute when unmuting and remote mute is on', async () => {
243
+ // simulate remote mute
244
+ video.handleServerRemoteMuteUpdate(meeting, true, true);
243
245
 
244
- let serverResponseResolve;
246
+ // unmute
247
+ await simulateVideoMuteChange(false);
245
248
 
246
- MeetingUtil.remoteUpdateAudioVideo = sinon.stub().returns(
247
- new Promise((resolve) => {
248
- serverResponseResolve = resolve;
249
- })
250
- );
249
+ // check that remote unmute was sent to server
250
+ assert.calledOnce(meeting.members.muteMember);
251
+ assert.calledWith(meeting.members.muteMember, meeting.members.selfId, false, false);
251
252
 
252
- audio.handleClientRequest(meeting, true).then(() => {
253
- clientPromiseResolved = true;
254
- });
253
+ assert.isFalse(video.isMuted());
254
+ });
255
255
 
256
- // do a small delay to make sure that the client promise doesn't resolve in that time
257
- await testUtils.waitUntil(200);
258
- assert.isFalse(clientPromiseResolved);
256
+ it('does not video remote unmute when unmuting and remote mute is off', async () => {
257
+ // simulate remote mute
258
+ video.handleServerRemoteMuteUpdate(meeting, false, true);
259
259
 
260
- // now allow the server response to arrive, this should trigger the client promise to get resolved
261
- serverResponseResolve();
262
- await testUtils.flushPromises();
260
+ // unmute
261
+ await simulateVideoMuteChange(false);
262
+
263
+ // check that remote unmute was not sent to server
264
+ assert.notCalled(meeting.members.muteMember);
263
265
 
264
- assert.isTrue(clientPromiseResolved);
266
+ assert.isFalse(video.isMuted());
265
267
  });
266
268
 
267
- it('rejects client request promise if server request for local mute fails', async () => {
268
- MeetingUtil.remoteUpdateAudioVideo = sinon.stub().returns(
269
- new Promise((resolve, reject) => {
270
- reject();
271
- })
272
- );
269
+ it('calls setServerMuted with "clientRequestFailed" when server request for local mute fails', async () => {
270
+ MeetingUtil.remoteUpdateAudioVideo = sinon.stub().rejects(new Error('fake error'));
273
271
 
274
- assert.isRejected(audio.handleClientRequest(meeting, true));
272
+ await simulateAudioMuteChange(true);
273
+
274
+ assert.calledOnceWithExactly(
275
+ meeting.mediaProperties.audioStream.setServerMuted,
276
+ false,
277
+ 'clientRequestFailed'
278
+ );
275
279
  });
276
280
 
277
- it('rejects client request promise if server request for remote mute fails', async () => {
281
+ it('calls setServerMuted with "clientRequestFailed" if server request for remote mute fails', async () => {
278
282
  // we only send remote mute requests when we're unmuting, so first we need to do a remote mute
279
- audio.handleServerRemoteMuteUpdate(true, true);
283
+ audio.handleServerRemoteMuteUpdate(meeting, true, true);
284
+
285
+ await testUtils.flushPromises();
280
286
 
281
287
  // setup the stub to simulate server error response
282
288
  meeting.members.muteMember = sinon.stub().rejects();
289
+ meeting.mediaProperties.audioStream.setServerMuted.resetHistory();
283
290
 
284
- // try to unmute - it should fail
285
- await assert.isRejected(audio.handleClientRequest(meeting, false));
291
+ await simulateAudioMuteChange(false);
292
+
293
+ assert.calledOnceWithExactly(
294
+ meeting.mediaProperties.audioStream.setServerMuted,
295
+ true,
296
+ 'clientRequestFailed'
297
+ );
286
298
 
287
299
  // even though remote mute update in the server failed, isMuted() should still return true,
288
300
  // because of local mute
@@ -298,12 +310,13 @@ describe('plugin-meetings', () => {
298
310
  })
299
311
  );
300
312
 
301
- // simulate many client requests, with the last one matching the initial one
302
- audio.handleClientRequest(meeting, true);
303
- audio.handleClientRequest(meeting, false);
304
- audio.handleClientRequest(meeting, true);
305
- audio.handleClientRequest(meeting, false);
306
- audio.handleClientRequest(meeting, true);
313
+ // the stream is initially unmuted
314
+ // simulate many mute changes with the last one matching the first one
315
+ await simulateAudioMuteChange(true);
316
+ await simulateAudioMuteChange(false);
317
+ await simulateAudioMuteChange(true);
318
+ await simulateAudioMuteChange(false);
319
+ await simulateAudioMuteChange(true);
307
320
 
308
321
  // so far there should have been only 1 request to server (because our stub hasn't resolved yet
309
322
  // and MuteState sends only 1 server request at a time)
@@ -318,7 +331,7 @@ describe('plugin-meetings', () => {
318
331
  assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
319
332
  });
320
333
 
321
- it('queues up server requests when multiple client requests are received', async () => {
334
+ it('queues up server requests when multiple mute changes happen to local stream', async () => {
322
335
  let serverResponseResolve;
323
336
 
324
337
  MeetingUtil.remoteUpdateAudioVideo = sinon.stub().returns(
@@ -327,104 +340,286 @@ describe('plugin-meetings', () => {
327
340
  })
328
341
  );
329
342
 
330
- let firstClientPromiseResolved = false;
331
- let secondClientPromiseResolved = false;
332
-
333
343
  // 2 client requests, one after another without waiting for first one to resolve
334
- audio.handleClientRequest(meeting, true).then(() => {
335
- firstClientPromiseResolved = true;
336
- });
337
- audio.handleClientRequest(meeting, false).then(() => {
338
- secondClientPromiseResolved = true;
339
- });
340
-
341
- await testUtils.flushPromises();
344
+ await simulateAudioMuteChange(true);
345
+ await simulateAudioMuteChange(false);
342
346
 
343
347
  assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
344
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, true, undefined, meeting);
348
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, true, undefined);
345
349
 
346
350
  // now allow the first request to complete
347
351
  serverResponseResolve();
348
352
  await testUtils.flushPromises();
349
- assert.isTrue(firstClientPromiseResolved);
350
353
 
351
354
  // that should trigger the second server request to be sent
352
355
  assert.calledTwice(MeetingUtil.remoteUpdateAudioVideo);
353
- assert.strictEqual(false, MeetingUtil.remoteUpdateAudioVideo.getCall(1).args[0]);
354
- assert.strictEqual(undefined, MeetingUtil.remoteUpdateAudioVideo.getCall(1).args[1]);
355
- assert.strictEqual(meeting, MeetingUtil.remoteUpdateAudioVideo.getCall(1).args[2]);
356
+ assert.deepEqual(
357
+ [meeting, false, undefined],
358
+ MeetingUtil.remoteUpdateAudioVideo.getCall(1).args
359
+ );
356
360
 
357
361
  serverResponseResolve();
358
- await testUtils.flushPromises();
359
-
360
- assert.isTrue(secondClientPromiseResolved);
361
- });
362
-
363
- it('rejects client request to unmute if hard mute is used', (done) => {
364
- audio.handleServerRemoteMuteUpdate(true, false);
365
-
366
- audio
367
- .handleClientRequest(meeting, false)
368
- .then(() => {
369
- done(new Error('expected handleClientRequest to fail, but it did not!'));
370
- })
371
- .catch((e) => {
372
- assert.isTrue(e instanceof PermissionError);
373
- done();
374
- });
375
362
  });
376
363
 
377
364
  it('does not send remote mute for video', async () => {
378
365
  // mute
379
- await video.handleClientRequest(meeting, true);
366
+ await simulateVideoMuteChange(true);
380
367
 
381
368
  assert.isTrue(video.isMuted());
382
- assert.isTrue(video.isSelf());
383
369
 
384
370
  // check local mute is done, but not remote one
385
- assert.calledWith(Media.setLocalTrack, false, meeting.mediaProperties.videoTrack);
386
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, undefined, true, meeting);
371
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, true);
387
372
  assert.notCalled(meeting.members.muteMember);
388
373
 
389
- Media.setLocalTrack.resetHistory();
390
374
  MeetingUtil.remoteUpdateAudioVideo.resetHistory();
391
375
  meeting.members.muteMember.resetHistory();
392
376
 
393
377
  // unmute
394
- await video.handleClientRequest(meeting, false);
378
+ await simulateVideoMuteChange(false);
395
379
 
396
380
  assert.isFalse(video.isMuted());
397
- assert.isFalse(video.isSelf());
398
381
 
399
- assert.calledWith(Media.setLocalTrack, true, meeting.mediaProperties.videoTrack);
400
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, undefined, false, meeting);
382
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, false);
401
383
  assert.notCalled(meeting.members.muteMember);
402
384
  });
403
385
 
404
- it('sends correct audio value when sending local mute for video', async () => {
386
+ it('sends undefined value for the other media type when sending local mute', async () => {
405
387
  // make sure the meeting object has mute state machines for both audio and video
406
388
  meeting.audio = audio;
407
389
  meeting.video = video;
408
390
 
409
- // mute audio -> request sent to server should have video unmuted
410
- await audio.handleClientRequest(meeting, true);
411
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, true, false, meeting);
391
+ // mute audio -> the call to remoteUpdateAudioVideo should have video undefined
392
+ await simulateAudioMuteChange(true);
393
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, true, undefined);
412
394
  MeetingUtil.remoteUpdateAudioVideo.resetHistory();
413
395
 
414
- // now mute video -> request sent to server should have mute for both audio and video
415
- await video.handleClientRequest(meeting, true);
416
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, true, true, meeting);
396
+ // now mute video -> the call to remoteUpdateAudioVideo should have unmute for video and undefined for audio
397
+ await simulateVideoMuteChange(true);
398
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, true);
417
399
  MeetingUtil.remoteUpdateAudioVideo.resetHistory();
418
400
 
419
- // now unmute the audio -> request sent to server should still have video muted
420
- await audio.handleClientRequest(meeting, false);
421
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, false, true, meeting);
401
+ // now unmute the audio -> the call to remoteUpdateAudioVideo should have video undefined
402
+ await simulateAudioMuteChange(false);
403
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, false, undefined);
422
404
  MeetingUtil.remoteUpdateAudioVideo.resetHistory();
423
405
 
424
- // unmute video -> request sent to server should have both audio and video unmuted
425
- await video.handleClientRequest(meeting, false);
426
- assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, false, false, meeting);
406
+ // unmute video -> the call to remoteUpdateAudioVideo should have audio undefined
407
+ await simulateVideoMuteChange(false);
408
+ assert.calledWith(MeetingUtil.remoteUpdateAudioVideo, meeting, undefined, false);
427
409
  });
428
410
  });
411
+
412
+ describe('#init, #handleLocalStreamChange', () => {
413
+ let meeting;
414
+ let muteState;
415
+ let setServerMutedSpy;
416
+ let setMutedSpy, setUnmuteAllowedSpy;
417
+
418
+ const setupMeeting = (
419
+ mediaType,
420
+ remoteMuted = false,
421
+ muted = false,
422
+ defineStreams = true
423
+ ) => {
424
+ const remoteMuteField = mediaType === AUDIO ? 'remoteMuted' : 'remoteVideoMuted';
425
+
426
+ meeting = {
427
+ mediaProperties: {
428
+ audioStream: defineStreams
429
+ ? createFakeLocalStream('fake audio stream', muted)
430
+ : undefined,
431
+ videoStream: defineStreams
432
+ ? createFakeLocalStream('fake video stream', muted)
433
+ : undefined,
434
+ },
435
+ [remoteMuteField]: remoteMuted,
436
+ unmuteAllowed: true,
437
+ unmuteVideoAllowed: true,
438
+
439
+ locusInfo: {
440
+ onFullLocus: sinon.stub(),
441
+ },
442
+ members: {
443
+ selfId: 'fake self id',
444
+ muteMember: sinon.stub().resolves(),
445
+ },
446
+ };
447
+ };
448
+
449
+ const setup = async (mediaType, remoteMuted = false, muted = false, defineStreams = true) => {
450
+ setupMeeting(mediaType, remoteMuted, muted, defineStreams);
451
+
452
+ muteState = createMuteState(mediaType, meeting, true);
453
+ muteState.handleLocalStreamChange(meeting);
454
+
455
+ await testUtils.flushPromises();
456
+
457
+ MeetingUtil.remoteUpdateAudioVideo.resetHistory();
458
+ };
459
+
460
+ const setupSpies = (mediaType) => {
461
+ setUnmuteAllowedSpy =
462
+ mediaType === AUDIO
463
+ ? meeting.mediaProperties.audioStream?.setUnmuteAllowed
464
+ : meeting.mediaProperties.videoStream?.setUnmuteAllowed;
465
+ setServerMutedSpy =
466
+ mediaType === AUDIO
467
+ ? meeting.mediaProperties.audioStream?.setServerMuted
468
+ : meeting.mediaProperties.videoStream?.setServerMuted;
469
+ setMutedSpy =
470
+ mediaType === AUDIO
471
+ ? meeting.mediaProperties.audioStream?.setMuted
472
+ : meeting.mediaProperties.videoStream?.setMuted;
473
+
474
+ clearSpies();
475
+ };
476
+
477
+ const clearSpies = () => {
478
+ setUnmuteAllowedSpy?.resetHistory();
479
+ setServerMutedSpy?.resetHistory();
480
+ setMutedSpy?.resetHistory();
481
+ };
482
+ const tests = [
483
+ {mediaType: AUDIO, title: 'audio'},
484
+ {mediaType: VIDEO, title: 'video'},
485
+ ];
486
+
487
+ tests.forEach(({mediaType, title}) =>
488
+ describe(title, () => {
489
+ let originalRemoteUpdateAudioVideo;
490
+
491
+ beforeEach(() => {
492
+ originalRemoteUpdateAudioVideo = MeetingUtil.remoteUpdateAudioVideo;
493
+ MeetingUtil.remoteUpdateAudioVideo = sinon.stub().resolves({info: 'fake locus'});
494
+ });
495
+
496
+ afterEach(() => {
497
+ MeetingUtil.remoteUpdateAudioVideo = originalRemoteUpdateAudioVideo;
498
+ sinon.restore();
499
+ });
500
+
501
+ describe('#handleLocalStreamChange', () => {
502
+ it('calls init()', async () => {
503
+ await setup(mediaType);
504
+ const spy = sinon.spy(muteState, 'init');
505
+ muteState.handleLocalStreamChange(meeting);
506
+ assert.calledOnceWithExactly(spy, meeting);
507
+ });
508
+ });
509
+
510
+ describe('#init', () => {
511
+ // does the setup by calling new MuteState() so that MuteState.init() doesn't get called
512
+ const setupWithoutInit = async (
513
+ mediaType,
514
+ remoteMuted = false,
515
+ muted = false,
516
+ defineStreams = true
517
+ ) => {
518
+ setupMeeting(mediaType, remoteMuted, muted, defineStreams);
519
+
520
+ muteState = new MuteState(mediaType, meeting, true);
521
+ };
522
+
523
+ it('nothing goes bad when stream is undefined', async () => {
524
+ await setupWithoutInit(mediaType, false, false, false);
525
+ setupSpies(mediaType);
526
+
527
+ muteState.init(meeting);
528
+
529
+ assert.isTrue(muteState.state.client.localMute);
530
+ });
531
+
532
+ it('tests when stream muted is true and remoteMuted is false', async () => {
533
+ await setupWithoutInit(mediaType, false, true);
534
+ setupSpies(mediaType);
535
+
536
+ muteState.init(meeting);
537
+
538
+ assert.calledWith(setUnmuteAllowedSpy, muteState.state.server.unmuteAllowed);
539
+ assert.notCalled(setServerMutedSpy);
540
+ assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
541
+ assert.isTrue(muteState.state.client.localMute);
542
+ });
543
+
544
+ it('tests when stream muted is false and remoteMuted is false', async () => {
545
+ await setupWithoutInit(mediaType, false, false);
546
+ setupSpies(mediaType);
547
+
548
+ muteState.init(meeting);
549
+
550
+ assert.calledWith(setUnmuteAllowedSpy, muteState.state.server.unmuteAllowed);
551
+ assert.notCalled(setServerMutedSpy);
552
+ assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
553
+ assert.isFalse(muteState.state.client.localMute);
554
+ });
555
+
556
+ it('tests when remoteMuted is true', async () => {
557
+ // testing that muteLocalStream is called
558
+ await setupWithoutInit(mediaType, true);
559
+ setupSpies(mediaType);
560
+
561
+ muteState.init(meeting);
562
+
563
+ assert.calledWith(setUnmuteAllowedSpy, muteState.state.server.unmuteAllowed);
564
+ assert.calledOnceWithExactly(setServerMutedSpy, true, 'remotelyMuted');
565
+ });
566
+ });
567
+
568
+ describe('#handleLocalStreamMuteStateChange', () => {
569
+ it('checks when ignoreMuteStateChange is true nothing changes', async () => {
570
+ await setup(mediaType, false, false);
571
+ muteState.ignoreMuteStateChange = true;
572
+
573
+ muteState.handleLocalStreamMuteStateChange(meeting, true);
574
+ assert.notCalled(MeetingUtil.remoteUpdateAudioVideo);
575
+
576
+ assert.isFalse(muteState.state.client.localMute);
577
+ });
578
+
579
+ it('tests localMute - true to false', async () => {
580
+ await setup(mediaType, false, true);
581
+
582
+ muteState.handleLocalStreamMuteStateChange(meeting, false);
583
+ assert.equal(muteState.state.client.localMute, false);
584
+ assert.called(MeetingUtil.remoteUpdateAudioVideo);
585
+ });
586
+
587
+ it('tests localMute - false to true', async () => {
588
+ await setup(mediaType, false, false);
589
+
590
+ muteState.handleLocalStreamMuteStateChange(meeting, true);
591
+ assert.equal(muteState.state.client.localMute, true);
592
+ assert.called(MeetingUtil.remoteUpdateAudioVideo);
593
+ });
594
+ });
595
+
596
+ describe('#applyClientStateLocally', () => {
597
+ afterEach(() => {
598
+ sinon.restore();
599
+ });
600
+
601
+ it('calls setServerMuted on the stream', async () => {
602
+ await setup(mediaType);
603
+ setupSpies(mediaType);
604
+
605
+ muteState.applyClientStateLocally(meeting, 'somereason');
606
+ assert.calledOnceWithExactly(
607
+ setServerMutedSpy,
608
+ muteState.state.client.localMute,
609
+ 'somereason'
610
+ );
611
+ assert.notCalled(setMutedSpy);
612
+ });
613
+
614
+ it('nothing explodes when streams are undefined', async () => {
615
+ await setup(mediaType, false, false, false);
616
+ setupSpies(mediaType);
617
+
618
+ muteState.applyClientStateLocally(meeting, 'somereason');
619
+ });
620
+ });
621
+ })
622
+ );
623
+ });
429
624
  });
430
625
  });