@webex/plugin-meetings 3.0.0-beta.16 → 3.0.0-beta.160

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 (408) hide show
  1. package/README.md +45 -1
  2. package/dist/annotation/annotation.types.js +7 -0
  3. package/dist/annotation/annotation.types.js.map +1 -0
  4. package/dist/annotation/constants.js +49 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +359 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +212 -0
  9. package/dist/breakouts/breakout.js.map +1 -0
  10. package/dist/breakouts/collection.js +23 -0
  11. package/dist/breakouts/collection.js.map +1 -0
  12. package/dist/breakouts/edit-lock-error.js +52 -0
  13. package/dist/breakouts/edit-lock-error.js.map +1 -0
  14. package/dist/breakouts/events.js +43 -0
  15. package/dist/breakouts/events.js.map +1 -0
  16. package/dist/breakouts/index.js +1046 -0
  17. package/dist/breakouts/index.js.map +1 -0
  18. package/dist/breakouts/request.js +78 -0
  19. package/dist/breakouts/request.js.map +1 -0
  20. package/dist/breakouts/utils.js +67 -0
  21. package/dist/breakouts/utils.js.map +1 -0
  22. package/dist/common/errors/webex-errors.js +3 -2
  23. package/dist/common/errors/webex-errors.js.map +1 -1
  24. package/dist/common/logs/logger-proxy.js +1 -1
  25. package/dist/common/logs/logger-proxy.js.map +1 -1
  26. package/dist/config.js +6 -8
  27. package/dist/config.js.map +1 -1
  28. package/dist/constants.js +165 -26
  29. package/dist/constants.js.map +1 -1
  30. package/dist/controls-options-manager/constants.js +14 -0
  31. package/dist/controls-options-manager/constants.js.map +1 -0
  32. package/dist/controls-options-manager/enums.js +27 -0
  33. package/dist/controls-options-manager/enums.js.map +1 -0
  34. package/dist/controls-options-manager/index.js +297 -0
  35. package/dist/controls-options-manager/index.js.map +1 -0
  36. package/dist/controls-options-manager/types.js +7 -0
  37. package/dist/controls-options-manager/types.js.map +1 -0
  38. package/dist/controls-options-manager/util.js +300 -0
  39. package/dist/controls-options-manager/util.js.map +1 -0
  40. package/dist/index.js +77 -0
  41. package/dist/index.js.map +1 -1
  42. package/dist/locus-info/controlsUtils.js +91 -2
  43. package/dist/locus-info/controlsUtils.js.map +1 -1
  44. package/dist/locus-info/index.js +298 -24
  45. package/dist/locus-info/index.js.map +1 -1
  46. package/dist/locus-info/mediaSharesUtils.js +43 -1
  47. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  48. package/dist/locus-info/parser.js +2 -1
  49. package/dist/locus-info/parser.js.map +1 -1
  50. package/dist/locus-info/selfUtils.js +88 -14
  51. package/dist/locus-info/selfUtils.js.map +1 -1
  52. package/dist/media/index.js +39 -134
  53. package/dist/media/index.js.map +1 -1
  54. package/dist/media/properties.js +19 -97
  55. package/dist/media/properties.js.map +1 -1
  56. package/dist/mediaQualityMetrics/config.js +505 -493
  57. package/dist/mediaQualityMetrics/config.js.map +1 -1
  58. package/dist/meeting/in-meeting-actions.js +79 -1
  59. package/dist/meeting/in-meeting-actions.js.map +1 -1
  60. package/dist/meeting/index.js +2275 -2152
  61. package/dist/meeting/index.js.map +1 -1
  62. package/dist/meeting/locusMediaRequest.js +291 -0
  63. package/dist/meeting/locusMediaRequest.js.map +1 -0
  64. package/dist/meeting/muteState.js +229 -124
  65. package/dist/meeting/muteState.js.map +1 -1
  66. package/dist/meeting/request.js +191 -167
  67. package/dist/meeting/request.js.map +1 -1
  68. package/dist/meeting/request.type.js.map +1 -1
  69. package/dist/meeting/util.js +443 -443
  70. package/dist/meeting/util.js.map +1 -1
  71. package/dist/meeting-info/meeting-info-v2.js +157 -49
  72. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  73. package/dist/meeting-info/utilv2.js +20 -5
  74. package/dist/meeting-info/utilv2.js.map +1 -1
  75. package/dist/meetings/collection.js +22 -0
  76. package/dist/meetings/collection.js.map +1 -1
  77. package/dist/meetings/index.js +365 -73
  78. package/dist/meetings/index.js.map +1 -1
  79. package/dist/meetings/meetings.types.js +7 -0
  80. package/dist/meetings/meetings.types.js.map +1 -0
  81. package/dist/meetings/request.js +16 -12
  82. package/dist/meetings/request.js.map +1 -1
  83. package/dist/meetings/util.js +88 -1
  84. package/dist/meetings/util.js.map +1 -1
  85. package/dist/member/index.js +41 -0
  86. package/dist/member/index.js.map +1 -1
  87. package/dist/member/types.js +15 -0
  88. package/dist/member/types.js.map +1 -0
  89. package/dist/member/util.js +86 -3
  90. package/dist/member/util.js.map +1 -1
  91. package/dist/members/collection.js +10 -0
  92. package/dist/members/collection.js.map +1 -1
  93. package/dist/members/index.js +94 -11
  94. package/dist/members/index.js.map +1 -1
  95. package/dist/members/request.js +109 -39
  96. package/dist/members/request.js.map +1 -1
  97. package/dist/members/types.js +15 -0
  98. package/dist/members/types.js.map +1 -0
  99. package/dist/members/util.js +316 -233
  100. package/dist/members/util.js.map +1 -1
  101. package/dist/metrics/config.js +50 -14
  102. package/dist/metrics/config.js.map +1 -1
  103. package/dist/metrics/constants.js +3 -5
  104. package/dist/metrics/constants.js.map +1 -1
  105. package/dist/metrics/index.js +48 -29
  106. package/dist/metrics/index.js.map +1 -1
  107. package/dist/multistream/mediaRequestManager.js +265 -36
  108. package/dist/multistream/mediaRequestManager.js.map +1 -1
  109. package/dist/multistream/receiveSlot.js +52 -19
  110. package/dist/multistream/receiveSlot.js.map +1 -1
  111. package/dist/multistream/receiveSlotManager.js +53 -33
  112. package/dist/multistream/receiveSlotManager.js.map +1 -1
  113. package/dist/multistream/remoteMedia.js +44 -18
  114. package/dist/multistream/remoteMedia.js.map +1 -1
  115. package/dist/multistream/remoteMediaGroup.js +60 -3
  116. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  117. package/dist/multistream/remoteMediaManager.js +322 -103
  118. package/dist/multistream/remoteMediaManager.js.map +1 -1
  119. package/dist/networkQualityMonitor/index.js +4 -2
  120. package/dist/networkQualityMonitor/index.js.map +1 -1
  121. package/dist/reachability/index.js +117 -60
  122. package/dist/reachability/index.js.map +1 -1
  123. package/dist/reachability/request.js +12 -5
  124. package/dist/reachability/request.js.map +1 -1
  125. package/dist/reactions/constants.js +13 -0
  126. package/dist/reactions/constants.js.map +1 -0
  127. package/dist/reactions/reactions.js +2 -2
  128. package/dist/reactions/reactions.js.map +1 -1
  129. package/dist/reactions/reactions.type.js +18 -18
  130. package/dist/reactions/reactions.type.js.map +1 -1
  131. package/dist/reconnection-manager/index.js +190 -145
  132. package/dist/reconnection-manager/index.js.map +1 -1
  133. package/dist/recording-controller/enums.js +17 -0
  134. package/dist/recording-controller/enums.js.map +1 -0
  135. package/dist/recording-controller/index.js +343 -0
  136. package/dist/recording-controller/index.js.map +1 -0
  137. package/dist/recording-controller/util.js +63 -0
  138. package/dist/recording-controller/util.js.map +1 -0
  139. package/dist/roap/index.js +21 -29
  140. package/dist/roap/index.js.map +1 -1
  141. package/dist/roap/request.js +127 -92
  142. package/dist/roap/request.js.map +1 -1
  143. package/dist/roap/turnDiscovery.js +135 -53
  144. package/dist/roap/turnDiscovery.js.map +1 -1
  145. package/dist/statsAnalyzer/global.js +1 -93
  146. package/dist/statsAnalyzer/global.js.map +1 -1
  147. package/dist/statsAnalyzer/index.js +329 -314
  148. package/dist/statsAnalyzer/index.js.map +1 -1
  149. package/dist/statsAnalyzer/mqaUtil.js +103 -54
  150. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  151. package/dist/types/annotation/annotation.types.d.ts +43 -0
  152. package/dist/types/annotation/constants.d.ts +31 -0
  153. package/dist/types/annotation/index.d.ts +124 -0
  154. package/dist/types/breakouts/breakout.d.ts +8 -0
  155. package/dist/types/breakouts/collection.d.ts +5 -0
  156. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  157. package/dist/types/breakouts/events.d.ts +2 -0
  158. package/dist/types/breakouts/index.d.ts +5 -0
  159. package/dist/types/breakouts/request.d.ts +22 -0
  160. package/dist/types/breakouts/utils.d.ts +15 -0
  161. package/dist/types/common/browser-detection.d.ts +9 -0
  162. package/dist/types/common/collection.d.ts +48 -0
  163. package/dist/types/common/config.d.ts +2 -0
  164. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  165. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  166. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  167. package/dist/types/common/errors/media.d.ts +15 -0
  168. package/dist/types/common/errors/parameter.d.ts +15 -0
  169. package/dist/types/common/errors/password-error.d.ts +15 -0
  170. package/dist/types/common/errors/permission.d.ts +14 -0
  171. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  172. package/dist/types/common/errors/reconnection.d.ts +15 -0
  173. package/dist/types/common/errors/stats.d.ts +15 -0
  174. package/dist/types/common/errors/webex-errors.d.ts +69 -0
  175. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  176. package/dist/types/common/events/events-scope.d.ts +17 -0
  177. package/dist/types/common/events/events.d.ts +12 -0
  178. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  179. package/dist/types/common/events/util.d.ts +2 -0
  180. package/dist/types/common/logs/logger-config.d.ts +2 -0
  181. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  182. package/dist/types/common/logs/request.d.ts +34 -0
  183. package/dist/types/common/queue.d.ts +32 -0
  184. package/dist/types/config.d.ts +72 -0
  185. package/dist/types/constants.d.ts +978 -0
  186. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  187. package/dist/types/controls-options-manager/enums.d.ts +15 -0
  188. package/dist/types/controls-options-manager/index.d.ts +136 -0
  189. package/dist/types/controls-options-manager/types.d.ts +43 -0
  190. package/dist/types/controls-options-manager/util.d.ts +1 -0
  191. package/dist/types/index.d.ts +7 -0
  192. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  193. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  194. package/dist/types/locus-info/fullState.d.ts +2 -0
  195. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  196. package/dist/types/locus-info/index.d.ts +315 -0
  197. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  198. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  199. package/dist/types/locus-info/parser.d.ts +212 -0
  200. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  201. package/dist/types/media/index.d.ts +34 -0
  202. package/dist/types/media/properties.d.ts +86 -0
  203. package/dist/types/media/util.d.ts +2 -0
  204. package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
  205. package/dist/types/meeting/in-meeting-actions.d.ts +149 -0
  206. package/dist/types/meeting/index.d.ts +1516 -0
  207. package/dist/types/meeting/locusMediaRequest.d.ts +70 -0
  208. package/dist/types/meeting/muteState.d.ts +184 -0
  209. package/dist/types/meeting/request.d.ts +270 -0
  210. package/dist/types/meeting/request.type.d.ts +11 -0
  211. package/dist/types/meeting/state.d.ts +9 -0
  212. package/dist/types/meeting/util.d.ts +75 -0
  213. package/dist/types/meeting-info/collection.d.ts +20 -0
  214. package/dist/types/meeting-info/index.d.ts +57 -0
  215. package/dist/types/meeting-info/meeting-info-v2.d.ts +122 -0
  216. package/dist/types/meeting-info/request.d.ts +22 -0
  217. package/dist/types/meeting-info/util.d.ts +2 -0
  218. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  219. package/dist/types/meetings/collection.d.ts +31 -0
  220. package/dist/types/meetings/index.d.ts +364 -0
  221. package/dist/types/meetings/meetings.types.d.ts +4 -0
  222. package/dist/types/meetings/request.d.ts +27 -0
  223. package/dist/types/meetings/util.d.ts +18 -0
  224. package/dist/types/member/index.d.ts +157 -0
  225. package/dist/types/member/types.d.ts +21 -0
  226. package/dist/types/member/util.d.ts +2 -0
  227. package/dist/types/members/collection.d.ts +29 -0
  228. package/dist/types/members/index.d.ts +353 -0
  229. package/dist/types/members/request.d.ts +114 -0
  230. package/dist/types/members/types.d.ts +24 -0
  231. package/dist/types/members/util.d.ts +210 -0
  232. package/dist/types/metrics/config.d.ts +195 -0
  233. package/dist/types/metrics/constants.d.ts +55 -0
  234. package/dist/types/metrics/index.d.ts +169 -0
  235. package/dist/types/multistream/mediaRequestManager.d.ts +118 -0
  236. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  237. package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
  238. package/dist/types/multistream/remoteMedia.d.ts +72 -0
  239. package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
  240. package/dist/types/multistream/remoteMediaManager.d.ts +277 -0
  241. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  242. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  243. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  244. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  245. package/dist/types/reachability/index.d.ts +152 -0
  246. package/dist/types/reachability/request.d.ts +37 -0
  247. package/dist/types/reactions/constants.d.ts +3 -0
  248. package/dist/types/reactions/reactions.d.ts +4 -0
  249. package/dist/types/reactions/reactions.type.d.ts +52 -0
  250. package/dist/types/reconnection-manager/index.d.ts +126 -0
  251. package/dist/types/recording-controller/enums.d.ts +7 -0
  252. package/dist/types/recording-controller/index.d.ts +193 -0
  253. package/dist/types/recording-controller/util.d.ts +13 -0
  254. package/dist/types/roap/index.d.ts +77 -0
  255. package/dist/types/roap/request.d.ts +36 -0
  256. package/dist/types/roap/turnDiscovery.d.ts +91 -0
  257. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  258. package/dist/types/statsAnalyzer/index.d.ts +200 -0
  259. package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
  260. package/dist/types/transcription/index.d.ts +64 -0
  261. package/package.json +28 -21
  262. package/src/annotation/annotation.types.ts +52 -0
  263. package/src/annotation/constants.ts +36 -0
  264. package/src/annotation/index.ts +343 -0
  265. package/src/breakouts/README.md +220 -0
  266. package/src/breakouts/breakout.ts +180 -0
  267. package/src/breakouts/collection.ts +19 -0
  268. package/src/breakouts/edit-lock-error.ts +25 -0
  269. package/src/breakouts/events.ts +37 -0
  270. package/src/breakouts/index.ts +921 -0
  271. package/src/breakouts/request.ts +55 -0
  272. package/src/breakouts/utils.ts +57 -0
  273. package/src/common/errors/webex-errors.ts +6 -2
  274. package/src/common/logs/logger-proxy.ts +1 -1
  275. package/src/config.ts +5 -7
  276. package/src/constants.ts +155 -20
  277. package/src/controls-options-manager/constants.ts +5 -0
  278. package/src/controls-options-manager/enums.ts +18 -0
  279. package/src/controls-options-manager/index.ts +278 -0
  280. package/src/controls-options-manager/types.ts +59 -0
  281. package/src/controls-options-manager/util.ts +286 -0
  282. package/src/index.ts +34 -0
  283. package/src/locus-info/controlsUtils.ts +108 -0
  284. package/src/locus-info/index.ts +310 -21
  285. package/src/locus-info/mediaSharesUtils.ts +48 -0
  286. package/src/locus-info/parser.ts +2 -1
  287. package/src/locus-info/selfUtils.ts +80 -2
  288. package/src/media/index.ts +70 -142
  289. package/src/media/properties.ts +41 -104
  290. package/src/mediaQualityMetrics/config.ts +379 -377
  291. package/src/meeting/in-meeting-actions.ts +156 -0
  292. package/src/meeting/index.ts +1744 -1767
  293. package/src/meeting/locusMediaRequest.ts +309 -0
  294. package/src/meeting/muteState.ts +228 -132
  295. package/src/meeting/request.ts +100 -91
  296. package/src/meeting/request.type.ts +2 -0
  297. package/src/meeting/util.ts +421 -421
  298. package/src/meeting-info/meeting-info-v2.ts +134 -13
  299. package/src/meeting-info/utilv2.ts +13 -3
  300. package/src/meetings/collection.ts +20 -0
  301. package/src/meetings/index.ts +385 -83
  302. package/src/meetings/meetings.types.ts +12 -0
  303. package/src/meetings/request.ts +3 -1
  304. package/src/meetings/util.ts +103 -4
  305. package/src/member/index.ts +40 -0
  306. package/src/member/types.ts +24 -0
  307. package/src/member/util.ts +81 -1
  308. package/src/members/collection.ts +8 -0
  309. package/src/members/index.ts +108 -6
  310. package/src/members/request.ts +98 -17
  311. package/src/members/types.ts +28 -0
  312. package/src/members/util.ts +319 -240
  313. package/src/metrics/config.ts +49 -10
  314. package/src/metrics/constants.ts +2 -4
  315. package/src/metrics/index.ts +43 -27
  316. package/src/multistream/mediaRequestManager.ts +337 -63
  317. package/src/multistream/receiveSlot.ts +68 -26
  318. package/src/multistream/receiveSlotManager.ts +61 -38
  319. package/src/multistream/remoteMedia.ts +29 -3
  320. package/src/multistream/remoteMediaGroup.ts +61 -2
  321. package/src/multistream/remoteMediaManager.ts +260 -66
  322. package/src/networkQualityMonitor/index.ts +6 -6
  323. package/src/reachability/index.ts +75 -25
  324. package/src/reachability/request.ts +10 -5
  325. package/src/reactions/constants.ts +4 -0
  326. package/src/reactions/reactions.ts +4 -4
  327. package/src/reactions/reactions.type.ts +28 -3
  328. package/src/reconnection-manager/index.ts +53 -32
  329. package/src/recording-controller/enums.ts +8 -0
  330. package/src/recording-controller/index.ts +315 -0
  331. package/src/recording-controller/util.ts +58 -0
  332. package/src/roap/index.ts +21 -30
  333. package/src/roap/request.ts +51 -52
  334. package/src/roap/turnDiscovery.ts +51 -27
  335. package/src/statsAnalyzer/global.ts +1 -94
  336. package/src/statsAnalyzer/index.ts +380 -390
  337. package/src/statsAnalyzer/mqaUtil.ts +106 -99
  338. package/test/integration/spec/converged-space-meetings.js +233 -0
  339. package/test/integration/spec/journey.js +331 -254
  340. package/test/integration/spec/space-meeting.js +77 -4
  341. package/test/unit/spec/annotation/index.ts +436 -0
  342. package/test/unit/spec/breakouts/breakout.ts +233 -0
  343. package/test/unit/spec/breakouts/collection.ts +15 -0
  344. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  345. package/test/unit/spec/breakouts/events.ts +77 -0
  346. package/test/unit/spec/breakouts/index.ts +1790 -0
  347. package/test/unit/spec/breakouts/request.ts +104 -0
  348. package/test/unit/spec/breakouts/utils.js +72 -0
  349. package/test/unit/spec/controls-options-manager/index.js +287 -0
  350. package/test/unit/spec/controls-options-manager/util.js +518 -0
  351. package/test/unit/spec/fixture/locus.js +1 -0
  352. package/test/unit/spec/locus-info/controlsUtils.js +303 -30
  353. package/test/unit/spec/locus-info/index.js +616 -4
  354. package/test/unit/spec/locus-info/mediaSharesUtils.ts +22 -0
  355. package/test/unit/spec/locus-info/selfConstant.js +38 -0
  356. package/test/unit/spec/locus-info/selfUtils.js +249 -0
  357. package/test/unit/spec/media/index.ts +118 -22
  358. package/test/unit/spec/media/properties.ts +9 -9
  359. package/test/unit/spec/meeting/in-meeting-actions.ts +76 -0
  360. package/test/unit/spec/meeting/index.js +2496 -1375
  361. package/test/unit/spec/meeting/locusMediaRequest.ts +436 -0
  362. package/test/unit/spec/meeting/muteState.js +370 -208
  363. package/test/unit/spec/meeting/request.js +354 -42
  364. package/test/unit/spec/meeting/utils.js +268 -156
  365. package/test/unit/spec/meeting-info/meetinginfov2.js +383 -5
  366. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  367. package/test/unit/spec/meetings/collection.js +14 -0
  368. package/test/unit/spec/meetings/index.js +866 -120
  369. package/test/unit/spec/meetings/utils.js +206 -2
  370. package/test/unit/spec/member/index.js +24 -0
  371. package/test/unit/spec/member/util.js +384 -32
  372. package/test/unit/spec/members/index.js +320 -1
  373. package/test/unit/spec/members/request.js +206 -27
  374. package/test/unit/spec/members/utils.js +184 -0
  375. package/test/unit/spec/metrics/index.js +98 -0
  376. package/test/unit/spec/multistream/mediaRequestManager.ts +1012 -109
  377. package/test/unit/spec/multistream/receiveSlot.ts +77 -18
  378. package/test/unit/spec/multistream/receiveSlotManager.ts +69 -39
  379. package/test/unit/spec/multistream/remoteMedia.ts +32 -2
  380. package/test/unit/spec/multistream/remoteMediaGroup.ts +271 -5
  381. package/test/unit/spec/multistream/remoteMediaManager.ts +672 -65
  382. package/test/unit/spec/networkQualityMonitor/index.js +4 -4
  383. package/test/unit/spec/reachability/index.ts +176 -25
  384. package/test/unit/spec/reachability/request.js +66 -0
  385. package/test/unit/spec/reconnection-manager/index.js +46 -13
  386. package/test/unit/spec/recording-controller/index.js +231 -0
  387. package/test/unit/spec/recording-controller/util.js +102 -0
  388. package/test/unit/spec/roap/index.ts +21 -51
  389. package/test/unit/spec/roap/request.ts +187 -0
  390. package/test/unit/spec/roap/turnDiscovery.ts +73 -34
  391. package/test/unit/spec/stats-analyzer/index.js +94 -43
  392. package/test/utils/constants.js +9 -0
  393. package/test/utils/integrationTestUtils.js +46 -0
  394. package/test/utils/testUtils.js +0 -45
  395. package/test/utils/webex-config.js +4 -0
  396. package/test/utils/webex-test-users.js +7 -3
  397. package/tsconfig.json +6 -0
  398. package/dist/media/internal-media-core-wrapper.js +0 -18
  399. package/dist/media/internal-media-core-wrapper.js.map +0 -1
  400. package/dist/meeting/effectsState.js +0 -262
  401. package/dist/meeting/effectsState.js.map +0 -1
  402. package/dist/multistream/multistreamMedia.js +0 -106
  403. package/dist/multistream/multistreamMedia.js.map +0 -1
  404. package/src/index.js +0 -15
  405. package/src/media/internal-media-core-wrapper.ts +0 -9
  406. package/src/meeting/effectsState.ts +0 -211
  407. package/src/multistream/multistreamMedia.ts +0 -93
  408. package/test/unit/spec/meeting/effectsState.js +0 -281
@@ -24,7 +24,7 @@ describe('plugin-meetings', () => {
24
24
  };
25
25
 
26
26
  const configObject = {
27
- mediaType: 'video',
27
+ mediaType: 'video-send',
28
28
  remoteRtpResults: {
29
29
  id: 'RTCRemoteInboundRtpVideoStream_2411086660',
30
30
  timestamp: 1624472676193.79,
@@ -42,12 +42,12 @@ describe('plugin-meetings', () => {
42
42
  roundTripTimeMeasurements: 14,
43
43
  },
44
44
  statsAnalyzerCurrentStats: {
45
- audio: {
45
+ 'audio-send': {
46
46
  send: {
47
47
  currentPacketLossRatio: 8,
48
48
  },
49
49
  },
50
- video: {
50
+ 'video-send': {
51
51
  send: {
52
52
  currentPacketLossRatio: 10,
53
53
  },
@@ -83,7 +83,7 @@ describe('plugin-meetings', () => {
83
83
  }),
84
84
  sinon.match(EVENT_TRIGGERS.NETWORK_QUALITY),
85
85
  sinon.match({
86
- mediaType: 'video',
86
+ mediaType: 'video-send',
87
87
  networkQualityScore: 0,
88
88
  })
89
89
  )
@@ -1,50 +1,201 @@
1
1
  import {assert} from '@webex/test-helper-chai';
2
- import Reachability from '@webex/plugin-meetings/src/reachability/';
2
+ import MockWebex from '@webex/test-helper-mock-webex';
3
+ import sinon from 'sinon';
4
+ import Reachability, {ICECandidateResult} from '@webex/plugin-meetings/src/reachability/';
3
5
 
4
6
  describe('isAnyClusterReachable', () => {
5
- before(function () {
6
- this.jsdom = require('jsdom-global')('', {url: 'http://localhost'});
7
- });
8
- after(function () {
9
- this.jsdom();
10
- });
7
+ let webex;
11
8
 
12
- afterEach(() => {
13
- window.localStorage.clear();
9
+ beforeEach(() => {
10
+ webex = new MockWebex();
14
11
  });
15
12
 
16
- const checkIsClusterReachable = (mockStorage: any, expectedValue: boolean) => {
13
+ const checkIsClusterReachable = async (mockStorage: any, expectedValue: boolean) => {
17
14
  if (mockStorage) {
18
- window.localStorage.setItem('reachability.result', JSON.stringify(mockStorage));
15
+ await webex.boundedStorage.put(
16
+ 'Reachability',
17
+ 'reachability.result',
18
+ JSON.stringify(mockStorage)
19
+ );
19
20
  }
20
- const reachability = new Reachability({});
21
+ const reachability = new Reachability(webex);
21
22
 
22
- const result = reachability.isAnyClusterReachable();
23
+ const result = await reachability.isAnyClusterReachable();
23
24
 
24
25
  assert.equal(result, expectedValue);
25
26
  };
26
27
 
27
- it('returns true when udp is reachable', () => {
28
- checkIsClusterReachable({x: {udp: {reachable: 'true'}, tcp: {reachable: 'false'}}}, true);
28
+ it('returns true when udp is reachable', async () => {
29
+ await checkIsClusterReachable({x: {udp: {reachable: 'true'}, tcp: {reachable: 'false'}}}, true);
30
+ });
31
+
32
+ it('returns true when tcp is reachable', async () => {
33
+ await checkIsClusterReachable({x: {udp: {reachable: 'false'}, tcp: {reachable: 'true'}}}, true);
29
34
  });
30
35
 
31
- it('returns true when tcp is reachable', () => {
32
- checkIsClusterReachable({x: {udp: {reachable: 'false'}, tcp: {reachable: 'true'}}}, true);
36
+ it('returns true when both tcp and udp are reachable', async () => {
37
+ await checkIsClusterReachable({x: {udp: {reachable: 'true'}, tcp: {reachable: 'true'}}}, true);
33
38
  });
34
39
 
35
- it('returns true when both tcp and udp are reachable', () => {
36
- checkIsClusterReachable({x: {udp: {reachable: 'true'}, tcp: {reachable: 'true'}}}, true);
40
+ it('returns false when both tcp and udp are unreachable', async () => {
41
+ await checkIsClusterReachable({x: {udp: {reachable: 'false'}, tcp: {reachable: 'false'}}}, false);
37
42
  });
38
43
 
39
- it('returns false when both tcp and udp are unreachable', () => {
40
- checkIsClusterReachable({x: {udp: {reachable: 'false'}, tcp: {reachable: 'false'}}}, false);
44
+ it('returns false when reachability result is empty', async () => {
45
+ await checkIsClusterReachable({x: {}}, false);
41
46
  });
42
47
 
43
- it('returns false when reachability result is empty', () => {
44
- checkIsClusterReachable({x: {}}, false);
48
+ it('returns false when reachability.result item is not there', async () => {
49
+ await checkIsClusterReachable(undefined, false);
50
+ });
51
+ });
52
+
53
+ describe('gatherReachability', () => {
54
+ let webex;
55
+
56
+ beforeEach(async () => {
57
+ webex = new MockWebex();
58
+
59
+ await webex.boundedStorage.put(
60
+ 'Reachability',
61
+ 'reachability.result',
62
+ JSON.stringify({old: 'results'})
63
+ );
64
+ });
65
+
66
+ it('stores the reachability', async () => {
67
+ const reachability = new Reachability(webex);
68
+
69
+ const reachabilityResults = {
70
+ clusters: {
71
+ clusterId: {
72
+ udp: 'testUDP',
73
+ },
74
+ },
75
+ };
76
+ const getClustersResult = {
77
+ clusters: {clusterId: 'cluster'},
78
+ joinCookie: {id: 'id'},
79
+ };
80
+
81
+ reachability.reachabilityRequest.getClusters = sinon.stub().returns(getClustersResult);
82
+ (reachability as any).performReachabilityCheck = sinon.stub().returns(reachabilityResults);
83
+
84
+ const result = await reachability.gatherReachability();
85
+
86
+ assert.equal(result, reachabilityResults);
87
+
88
+ const storedResultForReachabilityResult = await webex.boundedStorage.get(
89
+ 'Reachability',
90
+ 'reachability.result'
91
+ );
92
+ const storedResultForJoinCookie = await webex.boundedStorage.get(
93
+ 'Reachability',
94
+ 'reachability.joinCookie'
95
+ );
96
+
97
+ assert.equal(JSON.stringify(result), storedResultForReachabilityResult);
98
+ assert.equal(JSON.stringify(getClustersResult.joinCookie), storedResultForJoinCookie);
45
99
  });
46
100
 
47
- it('returns false when reachability.result item is not there', () => {
48
- checkIsClusterReachable(undefined, false);
101
+ describe('clientMediaIPs', () => {
102
+ let testingClass: TestReachability;
103
+
104
+ class TestReachability extends Reachability {
105
+ public testParseIceResultsToReachabilityResults(iceResults: Array<ICECandidateResult>) {
106
+ return this.parseIceResultsToReachabilityResults(iceResults);
107
+ }
108
+ public testAddPublicIP(peerConnection: RTCPeerConnection, publicIP?: string | null) {
109
+ return this.addPublicIP(peerConnection, publicIP);
110
+ }
111
+ }
112
+ beforeEach(() => {
113
+ testingClass = new TestReachability({webex});
114
+ });
115
+
116
+ it('calls parseIceResultsToReachabilityResults correctly', () => {
117
+ const res = testingClass.testParseIceResultsToReachabilityResults([
118
+ {
119
+ clusterId: 'id1',
120
+ elapsed: '12312',
121
+ publicIPs: ['1.1.1.1'],
122
+ },
123
+ {
124
+ clusterId: 'id2',
125
+ elapsed: null,
126
+ publicIPs: ['1.1.1.1'],
127
+ },
128
+ {
129
+ clusterId: 'id2',
130
+ elapsed: '14123',
131
+ publicIPs: undefined,
132
+ },
133
+ ]);
134
+
135
+ assert.deepEqual(res, {
136
+ id1: {
137
+ tcp: {
138
+ clientMediaIPs: ['1.1.1.1'],
139
+ latencyInMilliseconds: '12312',
140
+ reachable: 'true',
141
+ },
142
+ udp: {
143
+ clientMediaIPs: ['1.1.1.1'],
144
+ latencyInMilliseconds: '12312',
145
+ reachable: 'true',
146
+ },
147
+ },
148
+ id2: {
149
+ tcp: {
150
+ latencyInMilliseconds: '14123',
151
+ reachable: 'true',
152
+ },
153
+ udp: {
154
+ latencyInMilliseconds: '14123',
155
+ reachable: 'true',
156
+ },
157
+ },
158
+ });
159
+ });
160
+
161
+ it('calls addPublicIP correctly with no existing public APIs', () => {
162
+ const peerConnection = {
163
+ connectionState: 'not_closed',
164
+ };
165
+
166
+ testingClass.testAddPublicIP(peerConnection as RTCPeerConnection, '1.1.1.1');
167
+
168
+ assert.deepEqual(peerConnection, {
169
+ connectionState: 'not_closed',
170
+ publicIPs: ['1.1.1.1'],
171
+ });
172
+ });
173
+
174
+ it('calls addPublicIP correctly with existing public APIs', () => {
175
+ const peerConnection = {
176
+ connectionState: 'not_closed',
177
+ publicIPs: ['2.2.2.2'],
178
+ };
179
+
180
+ testingClass.testAddPublicIP(peerConnection as any, '1.1.1.1');
181
+
182
+ assert.deepEqual(peerConnection, {
183
+ connectionState: 'not_closed',
184
+ publicIPs: ['2.2.2.2', '1.1.1.1'],
185
+ });
186
+ });
187
+
188
+ it('calls addPublicIP correctly null publicAPI', () => {
189
+ const peerConnection = {
190
+ connectionState: 'not_closed',
191
+ };
192
+
193
+ testingClass.testAddPublicIP(peerConnection as RTCPeerConnection, null);
194
+
195
+ assert.deepEqual(peerConnection, {
196
+ connectionState: 'not_closed',
197
+ publicIPs: null,
198
+ });
199
+ });
49
200
  });
50
201
  });
@@ -0,0 +1,66 @@
1
+ import sinon from 'sinon';
2
+ import {assert} from '@webex/test-helper-chai';
3
+ import MockWebex from '@webex/test-helper-mock-webex';
4
+ import Meetings from '@webex/plugin-meetings';
5
+ import ReachabilityRequest from '@webex/plugin-meetings/src/reachability/request';
6
+
7
+
8
+ describe('plugin-meetings/reachability', () => {
9
+ let reachabilityRequest;
10
+ let webex;
11
+
12
+ beforeEach(() => {
13
+ webex = new MockWebex({
14
+ children: {
15
+ meetings: Meetings,
16
+ },
17
+ });
18
+
19
+ webex.meetings.clientRegion = {
20
+ countryCode: 'US',
21
+ regionCode: 'WEST-COAST',
22
+ };
23
+
24
+ webex.internal = {
25
+ services: {
26
+ get: sinon.mock().returns('locusUrl'),
27
+ waitForCatalog: sinon.mock().returns(Promise.resolve({})),
28
+ },
29
+ };
30
+
31
+
32
+ reachabilityRequest = new ReachabilityRequest(webex);
33
+
34
+ });
35
+
36
+ describe('#getClusters', () => {
37
+ it('sends a GET request with the correct params', async () => {
38
+ webex.request = sinon.mock().returns(Promise.resolve({
39
+ body: {
40
+ clusterClasses: {
41
+ hybridMedia: ["clusterId"]
42
+ },
43
+ clusters: {"clusterId": {
44
+ udp: "testUDP"
45
+ }},
46
+ joinCookie: {anycastEntryPoint: "aws-eu-west-1"}
47
+ }
48
+ }));
49
+
50
+ const res = await reachabilityRequest.getClusters();
51
+
52
+ const requestParams = webex.request.getCall(0).args[0];
53
+
54
+ assert.equal(requestParams.method, 'GET');
55
+ assert.equal(requestParams.resource, `clusters`);
56
+ assert.equal(requestParams.api, 'calliopeDiscovery');
57
+ assert.equal(requestParams.shouldRefreshAccessToken, false);
58
+
59
+ assert.deepEqual(requestParams.qs, {
60
+ JCSupport: 1,
61
+ });
62
+ assert.deepEqual(res.clusters.clusterId, {udp: "testUDP", isVideoMesh: true})
63
+ assert.deepEqual(res.joinCookie, {anycastEntryPoint: "aws-eu-west-1"})
64
+ });
65
+ });
66
+ });
@@ -12,13 +12,16 @@ sinon.assert.expose(chai.assert, {prefix: ''});
12
12
 
13
13
  describe('plugin-meetings', () => {
14
14
  describe('ReconnectionManager.reconnect', () => {
15
- it('uses correct TURN TLS information on the new connection', async () => {
16
- Metrics.postEvent = sinon.stub();
15
+ let fakeMediaConnection;
16
+ let fakeMeeting;
17
17
 
18
- const fakeMediaConnection = {
18
+ beforeEach(() => {
19
+ Metrics.postEvent = sinon.stub();
20
+ fakeMediaConnection = {
19
21
  initiateOffer: sinon.stub().resolves({}),
22
+ reconnect: sinon.stub().resolves({}),
20
23
  };
21
- const fakeMeeting = {
24
+ fakeMeeting = {
22
25
  closePeerConnections: sinon.stub().resolves({}),
23
26
  createMediaConnection: sinon.stub().returns(fakeMediaConnection),
24
27
  config: {
@@ -37,6 +40,11 @@ describe('plugin-meetings', () => {
37
40
  },
38
41
  mediaProperties: {
39
42
  unsetPeerConnection: sinon.stub(),
43
+ webrtcMediaConnection: fakeMediaConnection,
44
+ },
45
+ mediaRequestManagers: {
46
+ audio: {commit: sinon.stub(), clearPreviousRequests: sinon.stub()},
47
+ video: {commit: sinon.stub(), clearPreviousRequests: sinon.stub()},
40
48
  },
41
49
  roap: {
42
50
  doTurnDiscovery: sinon.stub().resolves({
@@ -58,21 +66,46 @@ describe('plugin-meetings', () => {
58
66
  },
59
67
  },
60
68
  };
69
+ });
61
70
 
71
+ it('uses correct TURN TLS information on the reconnection', async () => {
62
72
  const rm = new ReconnectionManager(fakeMeeting);
63
73
 
64
74
  await rm.reconnect();
65
75
 
66
- assert.calledOnce(fakeMeeting.closePeerConnections);
67
- assert.calledOnce(fakeMeeting.mediaProperties.unsetPeerConnection);
68
76
  assert.calledOnce(fakeMeeting.roap.doTurnDiscovery);
69
- assert.calledOnce(fakeMeeting.createMediaConnection);
70
- assert.calledWith(fakeMeeting.createMediaConnection, {
71
- url: 'fake_turn_url',
72
- username: 'fake_turn_username',
73
- password: 'fake_turn_password',
74
- });
75
- assert.calledOnce(fakeMediaConnection.initiateOffer);
77
+ assert.calledOnce(fakeMediaConnection.reconnect);
78
+ assert.calledWith(fakeMediaConnection.reconnect, [
79
+ {
80
+ urls: 'fake_turn_url',
81
+ username: 'fake_turn_username',
82
+ credential: 'fake_turn_password',
83
+ },
84
+ ]);
85
+ });
86
+
87
+ it('does not clear previous requests and re-request media for non-multistream meetings', async () => {
88
+ fakeMeeting.isMultistream = false;
89
+ const rm = new ReconnectionManager(fakeMeeting);
90
+
91
+ await rm.reconnect();
92
+
93
+ assert.notCalled(fakeMeeting.mediaRequestManagers.audio.clearPreviousRequests);
94
+ assert.notCalled(fakeMeeting.mediaRequestManagers.video.clearPreviousRequests);
95
+ assert.notCalled(fakeMeeting.mediaRequestManagers.audio.commit);
96
+ assert.notCalled(fakeMeeting.mediaRequestManagers.video.commit);
97
+ });
98
+
99
+ it('does clear previous requests and re-request media for multistream meetings', async () => {
100
+ fakeMeeting.isMultistream = true;
101
+ const rm = new ReconnectionManager(fakeMeeting);
102
+
103
+ await rm.reconnect();
104
+
105
+ assert.calledOnce(fakeMeeting.mediaRequestManagers.audio.clearPreviousRequests);
106
+ assert.calledOnce(fakeMeeting.mediaRequestManagers.video.clearPreviousRequests);
107
+ assert.calledOnce(fakeMeeting.mediaRequestManagers.audio.commit);
108
+ assert.calledOnce(fakeMeeting.mediaRequestManagers.video.commit);
76
109
  });
77
110
  });
78
111
 
@@ -0,0 +1,231 @@
1
+ import RecordingController from '@webex/plugin-meetings/src/recording-controller';
2
+ import sinon from 'sinon';
3
+ import {assert} from '@webex/test-helper-chai';
4
+ import { HTTP_VERBS } from '@webex/plugin-meetings/src/constants';
5
+
6
+ describe('plugin-meetings', () => {
7
+ describe('recording-controller tests', () => {
8
+ describe('index', () => {
9
+ let request;
10
+
11
+ describe('class tests', () => {
12
+ it('can set and extract new values later on', () => {
13
+ const controller = new RecordingController({});
14
+ assert.isUndefined(controller.getServiceUrl());
15
+ assert.isUndefined(controller.getSessionId());
16
+ assert.isUndefined(controller.getLocusUrl());
17
+ assert.isUndefined(controller.getLocusId());
18
+ controller.set({
19
+ serviceUrl: 'test',
20
+ sessionId: 'testId',
21
+ locusUrl: 'test/id',
22
+ displayHints: [],
23
+ })
24
+ assert(controller.getServiceUrl(), 'test');
25
+ assert(controller.getSessionId(), 'testId');
26
+ assert(controller.getLocusUrl(), 'test/id');
27
+ assert(controller.getLocusId(), 'id');
28
+ });
29
+ });
30
+
31
+
32
+ describe('legacy locus style recording', () => {
33
+ const locusUrl = 'locusUrl';
34
+ let controller;
35
+
36
+ beforeEach(() => {
37
+ request = {
38
+ request: sinon.stub().returns(Promise.resolve()),
39
+ };
40
+
41
+ controller = new RecordingController(request);
42
+
43
+ controller.set({
44
+ locusUrl,
45
+ displayHints: [],
46
+ })
47
+
48
+ });
49
+
50
+ describe('startRecording', () => {
51
+ it('rejects when correct display hint is not present', () => {
52
+ const result = controller.startRecording();
53
+
54
+ assert.notCalled(request.request);
55
+
56
+ assert.isRejected(result);
57
+ });
58
+
59
+ it('can start recording when the correct display hint is present', () => {
60
+ controller.setDisplayHints(['RECORDING_CONTROL_START']);
61
+
62
+ const result = controller.startRecording();
63
+
64
+ assert.calledWith(request.request, {uri: `${locusUrl}/controls`, body: {record: {recording: true, paused: false}}, method: HTTP_VERBS.PATCH});
65
+
66
+ assert.deepEqual(result, request.request.firstCall.returnValue);
67
+ });
68
+ });
69
+
70
+ describe('stopRecording', () => {
71
+ it('rejects when correct display hint is not present', () => {
72
+ const result = controller.stopRecording();
73
+
74
+ assert.notCalled(request.request);
75
+
76
+ assert.isRejected(result);
77
+ });
78
+
79
+ it('can stop recording when the correct display hint is present', () => {
80
+ controller.setDisplayHints(['RECORDING_CONTROL_STOP']);
81
+
82
+ const result = controller.stopRecording();
83
+
84
+ assert.calledWith(request.request, {uri: `${locusUrl}/controls`, body: {record: {recording: false, paused: false}}, method: HTTP_VERBS.PATCH});
85
+
86
+ assert.deepEqual(result, request.request.firstCall.returnValue);
87
+ });
88
+ });
89
+
90
+ describe('pauseRecording', () => {
91
+ it('rejects when correct display hint is not present', () => {
92
+ const result = controller.pauseRecording();
93
+
94
+ assert.notCalled(request.request);
95
+
96
+ assert.isRejected(result);
97
+ });
98
+
99
+ it('can pause recording when the correct display hint is present', () => {
100
+ controller.setDisplayHints(['RECORDING_CONTROL_PAUSE']);
101
+
102
+ const result = controller.pauseRecording();
103
+
104
+ assert.calledWith(request.request, {uri: `${locusUrl}/controls`, body: {record: {recording: true, paused: true}}, method: HTTP_VERBS.PATCH});
105
+
106
+ assert.deepEqual(result, request.request.firstCall.returnValue);
107
+ });
108
+ });
109
+
110
+ describe('resumeRecording', () => {
111
+ it('rejects when correct display hint is not present', () => {
112
+ const result = controller.pauseRecording();
113
+
114
+ assert.notCalled(request.request);
115
+
116
+ assert.isRejected(result);
117
+ });
118
+
119
+ it('can resume recording when the correct display hint is present', () => {
120
+ controller.setDisplayHints(['RECORDING_CONTROL_RESUME']);
121
+
122
+ const result = controller.resumeRecording();
123
+
124
+ assert.calledWith(request.request, {uri: `${locusUrl}/controls`, body: {record: {recording: true, paused: false}}, method: HTTP_VERBS.PATCH});
125
+
126
+ assert.deepEqual(result, request.request.firstCall.returnValue);
127
+ });
128
+ });
129
+ });
130
+
131
+ describe('recording streaming service style tests', () => {
132
+ let controller;
133
+
134
+ beforeEach(() => {
135
+ request = {
136
+ request: sinon.stub().returns(Promise.resolve()),
137
+ };
138
+
139
+ controller = new RecordingController(request);
140
+
141
+ controller.set({
142
+ serviceUrl: 'test',
143
+ sessionId: 'testId',
144
+ locusUrl: 'test/id',
145
+ displayHints: [],
146
+ })
147
+ });
148
+
149
+ describe('startRecording', () => {
150
+ it('rejects when correct display hint is not present', () => {
151
+ const result = controller.startRecording();
152
+
153
+ assert.notCalled(request.request);
154
+
155
+ assert.isRejected(result);
156
+ });
157
+
158
+ it('can start recording when the correct display hint is present', () => {
159
+ controller.setDisplayHints(['RECORDING_CONTROL_START']);
160
+
161
+ const result = controller.startRecording();
162
+
163
+ assert.calledWith(request.request, {uri: `test/loci/id/recording`, body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'start'}}, method: HTTP_VERBS.PUT});
164
+
165
+ assert.deepEqual(result, request.request.firstCall.returnValue);
166
+ });
167
+ });
168
+
169
+ describe('stopRecording', () => {
170
+ it('rejects when correct display hint is not present', () => {
171
+ const result = controller.pauseRecording();
172
+
173
+ assert.notCalled(request.request);
174
+
175
+ assert.isRejected(result);
176
+ });
177
+
178
+ it('can start recording when the correct display hint is present', () => {
179
+ controller.setDisplayHints(['RECORDING_CONTROL_STOP']);
180
+
181
+ const result = controller.stopRecording();
182
+
183
+ assert.calledWith(request.request, {uri: `test/loci/id/recording`, body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'stop'}}, method: HTTP_VERBS.PUT});
184
+
185
+ assert.deepEqual(result, request.request.firstCall.returnValue);
186
+ });
187
+ });
188
+
189
+ describe('pauseRecording', () => {
190
+ it('rejects when correct display hint is not present', () => {
191
+ const result = controller.pauseRecording();
192
+
193
+ assert.notCalled(request.request);
194
+
195
+ assert.isRejected(result);
196
+ });
197
+
198
+ it('can pause recording when the correct display hint is present', () => {
199
+ controller.setDisplayHints(['RECORDING_CONTROL_PAUSE']);
200
+
201
+ const result = controller.pauseRecording();
202
+
203
+ assert.calledWith(request.request, {uri: `test/loci/id/recording`, body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'pause'}}, method: HTTP_VERBS.PUT});
204
+
205
+ assert.deepEqual(result, request.request.firstCall.returnValue);
206
+ });
207
+ });
208
+
209
+ describe('resumeRecording', () => {
210
+ it('rejects when correct display hint is not present', () => {
211
+ const result = controller.resumeRecording();
212
+
213
+ assert.notCalled(request.request);
214
+
215
+ assert.isRejected(result);
216
+ });
217
+
218
+ it('can resume recording when the correct display hint is present', () => {
219
+ controller.setDisplayHints(['RECORDING_CONTROL_RESUME']);
220
+
221
+ const result = controller.resumeRecording();
222
+
223
+ assert.calledWith(request.request, {uri: `test/loci/id/recording`, body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'resume'}}, method: HTTP_VERBS.PUT});
224
+
225
+ assert.deepEqual(result, request.request.firstCall.returnValue);
226
+ });
227
+ });
228
+ });
229
+ });
230
+ });
231
+ });