@webex/plugin-meetings 3.0.0-beta.34 → 3.0.0-beta.340

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 (392) 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 +49 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +342 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +94 -15
  9. package/dist/breakouts/breakout.js.map +1 -1
  10. package/dist/breakouts/edit-lock-error.js +52 -0
  11. package/dist/breakouts/edit-lock-error.js.map +1 -0
  12. package/dist/breakouts/events.js +45 -0
  13. package/dist/breakouts/events.js.map +1 -0
  14. package/dist/breakouts/index.js +709 -35
  15. package/dist/breakouts/index.js.map +1 -1
  16. package/dist/breakouts/utils.js +45 -1
  17. package/dist/breakouts/utils.js.map +1 -1
  18. package/dist/common/errors/no-meeting-info.js +51 -0
  19. package/dist/common/errors/no-meeting-info.js.map +1 -0
  20. package/dist/common/errors/reclaim-host-role-errors.js +158 -0
  21. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  22. package/dist/common/errors/webex-errors.js +48 -7
  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/common/logs/request.js +5 -1
  27. package/dist/common/logs/request.js.map +1 -1
  28. package/dist/common/queue.js +24 -9
  29. package/dist/common/queue.js.map +1 -1
  30. package/dist/config.js +5 -10
  31. package/dist/config.js.map +1 -1
  32. package/dist/constants.js +233 -29
  33. package/dist/constants.js.map +1 -1
  34. package/dist/controls-options-manager/enums.js +14 -2
  35. package/dist/controls-options-manager/enums.js.map +1 -1
  36. package/dist/controls-options-manager/index.js +109 -15
  37. package/dist/controls-options-manager/index.js.map +1 -1
  38. package/dist/controls-options-manager/types.js +7 -0
  39. package/dist/controls-options-manager/types.js.map +1 -0
  40. package/dist/controls-options-manager/util.js +309 -18
  41. package/dist/controls-options-manager/util.js.map +1 -1
  42. package/dist/index.js +112 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/interpretation/collection.js +23 -0
  45. package/dist/interpretation/collection.js.map +1 -0
  46. package/dist/interpretation/index.js +366 -0
  47. package/dist/interpretation/index.js.map +1 -0
  48. package/dist/interpretation/siLanguage.js +25 -0
  49. package/dist/interpretation/siLanguage.js.map +1 -0
  50. package/dist/locus-info/controlsUtils.js +91 -2
  51. package/dist/locus-info/controlsUtils.js.map +1 -1
  52. package/dist/locus-info/index.js +383 -62
  53. package/dist/locus-info/index.js.map +1 -1
  54. package/dist/locus-info/infoUtils.js +7 -1
  55. package/dist/locus-info/infoUtils.js.map +1 -1
  56. package/dist/locus-info/mediaSharesUtils.js +57 -1
  57. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  58. package/dist/locus-info/parser.js +249 -72
  59. package/dist/locus-info/parser.js.map +1 -1
  60. package/dist/locus-info/selfUtils.js +89 -14
  61. package/dist/locus-info/selfUtils.js.map +1 -1
  62. package/dist/media/index.js +62 -116
  63. package/dist/media/index.js.map +1 -1
  64. package/dist/media/properties.js +73 -124
  65. package/dist/media/properties.js.map +1 -1
  66. package/dist/mediaQualityMetrics/config.js +1 -204
  67. package/dist/mediaQualityMetrics/config.js.map +1 -1
  68. package/dist/meeting/in-meeting-actions.js +86 -2
  69. package/dist/meeting/in-meeting-actions.js.map +1 -1
  70. package/dist/meeting/index.js +3927 -2960
  71. package/dist/meeting/index.js.map +1 -1
  72. package/dist/meeting/locusMediaRequest.js +292 -0
  73. package/dist/meeting/locusMediaRequest.js.map +1 -0
  74. package/dist/meeting/muteState.js +224 -131
  75. package/dist/meeting/muteState.js.map +1 -1
  76. package/dist/meeting/request.js +260 -196
  77. package/dist/meeting/request.js.map +1 -1
  78. package/dist/meeting/util.js +601 -417
  79. package/dist/meeting/util.js.map +1 -1
  80. package/dist/meeting-info/index.js +73 -7
  81. package/dist/meeting-info/index.js.map +1 -1
  82. package/dist/meeting-info/meeting-info-v2.js +192 -51
  83. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  84. package/dist/meeting-info/util.js +1 -1
  85. package/dist/meeting-info/util.js.map +1 -1
  86. package/dist/meeting-info/utilv2.js +36 -36
  87. package/dist/meeting-info/utilv2.js.map +1 -1
  88. package/dist/meetings/collection.js +39 -0
  89. package/dist/meetings/collection.js.map +1 -1
  90. package/dist/meetings/index.js +424 -116
  91. package/dist/meetings/index.js.map +1 -1
  92. package/dist/meetings/meetings.types.js +7 -0
  93. package/dist/meetings/meetings.types.js.map +1 -0
  94. package/dist/meetings/request.js +2 -0
  95. package/dist/meetings/request.js.map +1 -1
  96. package/dist/meetings/util.js +72 -6
  97. package/dist/meetings/util.js.map +1 -1
  98. package/dist/member/index.js +58 -0
  99. package/dist/member/index.js.map +1 -1
  100. package/dist/member/types.js +25 -0
  101. package/dist/member/types.js.map +1 -0
  102. package/dist/member/util.js +132 -25
  103. package/dist/member/util.js.map +1 -1
  104. package/dist/members/collection.js +10 -0
  105. package/dist/members/collection.js.map +1 -1
  106. package/dist/members/index.js +102 -6
  107. package/dist/members/index.js.map +1 -1
  108. package/dist/members/request.js +106 -38
  109. package/dist/members/request.js.map +1 -1
  110. package/dist/members/types.js +15 -0
  111. package/dist/members/types.js.map +1 -0
  112. package/dist/members/util.js +326 -232
  113. package/dist/members/util.js.map +1 -1
  114. package/dist/metrics/constants.js +16 -5
  115. package/dist/metrics/constants.js.map +1 -1
  116. package/dist/metrics/index.js +1 -446
  117. package/dist/metrics/index.js.map +1 -1
  118. package/dist/multistream/mediaRequestManager.js +228 -58
  119. package/dist/multistream/mediaRequestManager.js.map +1 -1
  120. package/dist/multistream/receiveSlot.js +29 -16
  121. package/dist/multistream/receiveSlot.js.map +1 -1
  122. package/dist/multistream/receiveSlotManager.js +39 -36
  123. package/dist/multistream/receiveSlotManager.js.map +1 -1
  124. package/dist/multistream/remoteMedia.js +44 -18
  125. package/dist/multistream/remoteMedia.js.map +1 -1
  126. package/dist/multistream/remoteMediaGroup.js +60 -3
  127. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  128. package/dist/multistream/remoteMediaManager.js +209 -59
  129. package/dist/multistream/remoteMediaManager.js.map +1 -1
  130. package/dist/multistream/sendSlotManager.js +233 -0
  131. package/dist/multistream/sendSlotManager.js.map +1 -0
  132. package/dist/reachability/clusterReachability.js +356 -0
  133. package/dist/reachability/clusterReachability.js.map +1 -0
  134. package/dist/reachability/index.js +273 -391
  135. package/dist/reachability/index.js.map +1 -1
  136. package/dist/reachability/request.js +17 -8
  137. package/dist/reachability/request.js.map +1 -1
  138. package/dist/reachability/util.js +29 -0
  139. package/dist/reachability/util.js.map +1 -0
  140. package/dist/reconnection-manager/index.js +214 -170
  141. package/dist/reconnection-manager/index.js.map +1 -1
  142. package/dist/recording-controller/index.js +21 -2
  143. package/dist/recording-controller/index.js.map +1 -1
  144. package/dist/recording-controller/util.js +9 -8
  145. package/dist/recording-controller/util.js.map +1 -1
  146. package/dist/roap/index.js +62 -35
  147. package/dist/roap/index.js.map +1 -1
  148. package/dist/roap/request.js +112 -97
  149. package/dist/roap/request.js.map +1 -1
  150. package/dist/roap/turnDiscovery.js +95 -38
  151. package/dist/roap/turnDiscovery.js.map +1 -1
  152. package/dist/rtcMetrics/constants.js +12 -0
  153. package/dist/rtcMetrics/constants.js.map +1 -0
  154. package/dist/rtcMetrics/index.js +142 -0
  155. package/dist/rtcMetrics/index.js.map +1 -0
  156. package/dist/statsAnalyzer/index.js +181 -214
  157. package/dist/statsAnalyzer/index.js.map +1 -1
  158. package/dist/statsAnalyzer/mqaUtil.js +22 -18
  159. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  160. package/dist/types/annotation/annotation.types.d.ts +42 -0
  161. package/dist/types/annotation/constants.d.ts +31 -0
  162. package/dist/types/annotation/index.d.ts +117 -0
  163. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  164. package/dist/types/breakouts/events.d.ts +8 -0
  165. package/dist/types/breakouts/utils.d.ts +14 -0
  166. package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
  167. package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
  168. package/dist/types/common/errors/webex-errors.d.ts +25 -1
  169. package/dist/types/common/logs/request.d.ts +2 -0
  170. package/dist/types/common/queue.d.ts +9 -7
  171. package/dist/types/config.d.ts +2 -7
  172. package/dist/types/constants.d.ts +201 -30
  173. package/dist/types/controls-options-manager/enums.d.ts +11 -1
  174. package/dist/types/controls-options-manager/index.d.ts +17 -1
  175. package/dist/types/controls-options-manager/types.d.ts +43 -0
  176. package/dist/types/controls-options-manager/util.d.ts +1 -7
  177. package/dist/types/index.d.ts +6 -4
  178. package/dist/types/interpretation/collection.d.ts +5 -0
  179. package/dist/types/interpretation/index.d.ts +5 -0
  180. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  181. package/dist/types/locus-info/index.d.ts +57 -4
  182. package/dist/types/locus-info/parser.d.ts +66 -6
  183. package/dist/types/media/index.d.ts +2 -0
  184. package/dist/types/media/properties.d.ts +34 -48
  185. package/dist/types/mediaQualityMetrics/config.d.ts +0 -128
  186. package/dist/types/meeting/in-meeting-actions.d.ts +86 -2
  187. package/dist/types/meeting/index.d.ts +506 -512
  188. package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
  189. package/dist/types/meeting/muteState.d.ts +93 -25
  190. package/dist/types/meeting/request.d.ts +72 -43
  191. package/dist/types/meeting/util.d.ts +101 -1
  192. package/dist/types/meeting-info/index.d.ts +13 -1
  193. package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
  194. package/dist/types/meetings/collection.d.ts +17 -0
  195. package/dist/types/meetings/index.d.ts +91 -21
  196. package/dist/types/meetings/meetings.types.d.ts +4 -0
  197. package/dist/types/member/index.d.ts +14 -0
  198. package/dist/types/member/types.d.ts +32 -0
  199. package/dist/types/members/collection.d.ts +5 -0
  200. package/dist/types/members/index.d.ts +35 -2
  201. package/dist/types/members/request.d.ts +73 -9
  202. package/dist/types/members/types.d.ts +25 -0
  203. package/dist/types/members/util.d.ts +214 -1
  204. package/dist/types/metrics/constants.d.ts +15 -4
  205. package/dist/types/metrics/index.d.ts +4 -111
  206. package/dist/types/multistream/mediaRequestManager.d.ts +72 -5
  207. package/dist/types/multistream/receiveSlot.d.ts +13 -11
  208. package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
  209. package/dist/types/multistream/remoteMedia.d.ts +8 -29
  210. package/dist/types/multistream/remoteMediaGroup.d.ts +0 -9
  211. package/dist/types/multistream/remoteMediaManager.d.ts +46 -2
  212. package/dist/types/multistream/sendSlotManager.d.ts +61 -0
  213. package/dist/types/reachability/clusterReachability.d.ts +109 -0
  214. package/dist/types/reachability/index.d.ts +60 -95
  215. package/dist/types/reachability/request.d.ts +7 -3
  216. package/dist/types/reachability/util.d.ts +8 -0
  217. package/dist/types/reconnection-manager/index.d.ts +19 -0
  218. package/dist/types/recording-controller/index.d.ts +15 -1
  219. package/dist/types/recording-controller/util.d.ts +5 -4
  220. package/dist/types/roap/index.d.ts +2 -1
  221. package/dist/types/roap/request.d.ts +15 -11
  222. package/dist/types/roap/turnDiscovery.d.ts +21 -3
  223. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  224. package/dist/types/rtcMetrics/index.d.ts +54 -0
  225. package/dist/types/statsAnalyzer/index.d.ts +29 -11
  226. package/dist/types/webinar/collection.d.ts +16 -0
  227. package/dist/types/webinar/index.d.ts +5 -0
  228. package/dist/webinar/collection.js +44 -0
  229. package/dist/webinar/collection.js.map +1 -0
  230. package/dist/webinar/index.js +69 -0
  231. package/dist/webinar/index.js.map +1 -0
  232. package/package.json +22 -19
  233. package/src/annotation/annotation.types.ts +50 -0
  234. package/src/annotation/constants.ts +36 -0
  235. package/src/annotation/index.ts +328 -0
  236. package/src/breakouts/README.md +42 -12
  237. package/src/breakouts/breakout.ts +67 -9
  238. package/src/breakouts/edit-lock-error.ts +25 -0
  239. package/src/breakouts/events.ts +56 -0
  240. package/src/breakouts/index.ts +592 -20
  241. package/src/breakouts/utils.ts +42 -0
  242. package/src/common/errors/no-meeting-info.ts +24 -0
  243. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  244. package/src/common/errors/webex-errors.ts +44 -2
  245. package/src/common/logs/logger-proxy.ts +1 -1
  246. package/src/common/logs/request.ts +5 -1
  247. package/src/common/queue.ts +22 -8
  248. package/src/config.ts +4 -9
  249. package/src/constants.ts +224 -20
  250. package/src/controls-options-manager/enums.ts +12 -0
  251. package/src/controls-options-manager/index.ts +116 -21
  252. package/src/controls-options-manager/types.ts +59 -0
  253. package/src/controls-options-manager/util.ts +294 -14
  254. package/src/index.ts +40 -0
  255. package/src/interpretation/README.md +60 -0
  256. package/src/interpretation/collection.ts +19 -0
  257. package/src/interpretation/index.ts +332 -0
  258. package/src/interpretation/siLanguage.ts +18 -0
  259. package/src/locus-info/controlsUtils.ts +108 -0
  260. package/src/locus-info/index.ts +413 -59
  261. package/src/locus-info/infoUtils.ts +10 -2
  262. package/src/locus-info/mediaSharesUtils.ts +64 -0
  263. package/src/locus-info/parser.ts +258 -47
  264. package/src/locus-info/selfUtils.ts +81 -5
  265. package/src/media/index.ts +102 -122
  266. package/src/media/properties.ts +87 -110
  267. package/src/mediaQualityMetrics/config.ts +0 -135
  268. package/src/meeting/in-meeting-actions.ts +171 -3
  269. package/src/meeting/index.ts +3276 -2555
  270. package/src/meeting/locusMediaRequest.ts +313 -0
  271. package/src/meeting/muteState.ts +223 -136
  272. package/src/meeting/request.ts +177 -121
  273. package/src/meeting/util.ts +588 -394
  274. package/src/meeting-info/index.ts +81 -8
  275. package/src/meeting-info/meeting-info-v2.ts +170 -14
  276. package/src/meeting-info/util.ts +1 -1
  277. package/src/meeting-info/utilv2.ts +23 -23
  278. package/src/meetings/collection.ts +33 -0
  279. package/src/meetings/index.ts +454 -125
  280. package/src/meetings/meetings.types.ts +12 -0
  281. package/src/meetings/request.ts +2 -0
  282. package/src/meetings/util.ts +80 -11
  283. package/src/member/index.ts +58 -0
  284. package/src/member/types.ts +38 -0
  285. package/src/member/util.ts +141 -25
  286. package/src/members/collection.ts +8 -0
  287. package/src/members/index.ts +134 -8
  288. package/src/members/request.ts +97 -17
  289. package/src/members/types.ts +29 -0
  290. package/src/members/util.ts +333 -240
  291. package/src/metrics/constants.ts +15 -4
  292. package/src/metrics/index.ts +1 -469
  293. package/src/multistream/mediaRequestManager.ts +277 -82
  294. package/src/multistream/receiveSlot.ts +31 -17
  295. package/src/multistream/receiveSlotManager.ts +34 -24
  296. package/src/multistream/remoteMedia.ts +27 -2
  297. package/src/multistream/remoteMediaGroup.ts +59 -0
  298. package/src/multistream/remoteMediaManager.ts +148 -30
  299. package/src/multistream/sendSlotManager.ts +170 -0
  300. package/src/reachability/clusterReachability.ts +320 -0
  301. package/src/reachability/index.ts +236 -342
  302. package/src/reachability/request.ts +17 -8
  303. package/src/reachability/util.ts +24 -0
  304. package/src/reconnection-manager/index.ts +128 -106
  305. package/src/recording-controller/index.ts +20 -3
  306. package/src/recording-controller/util.ts +26 -9
  307. package/src/roap/index.ts +63 -32
  308. package/src/roap/request.ts +100 -104
  309. package/src/roap/turnDiscovery.ts +48 -26
  310. package/src/rtcMetrics/constants.ts +3 -0
  311. package/src/rtcMetrics/index.ts +124 -0
  312. package/src/statsAnalyzer/index.ts +218 -289
  313. package/src/statsAnalyzer/mqaUtil.ts +28 -30
  314. package/src/webinar/collection.ts +31 -0
  315. package/src/webinar/index.ts +62 -0
  316. package/test/integration/spec/converged-space-meetings.js +60 -3
  317. package/test/integration/spec/journey.js +320 -261
  318. package/test/integration/spec/space-meeting.js +76 -3
  319. package/test/unit/spec/annotation/index.ts +418 -0
  320. package/test/unit/spec/breakouts/breakout.ts +118 -28
  321. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  322. package/test/unit/spec/breakouts/events.ts +89 -0
  323. package/test/unit/spec/breakouts/index.ts +1395 -69
  324. package/test/unit/spec/breakouts/utils.js +52 -1
  325. package/test/unit/spec/common/queue.js +31 -2
  326. package/test/unit/spec/controls-options-manager/index.js +163 -0
  327. package/test/unit/spec/controls-options-manager/util.js +576 -60
  328. package/test/unit/spec/fixture/locus.js +1 -0
  329. package/test/unit/spec/interpretation/collection.ts +15 -0
  330. package/test/unit/spec/interpretation/index.ts +589 -0
  331. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  332. package/test/unit/spec/locus-info/controlsUtils.js +316 -43
  333. package/test/unit/spec/locus-info/index.js +1304 -33
  334. package/test/unit/spec/locus-info/infoUtils.js +37 -15
  335. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  336. package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
  337. package/test/unit/spec/locus-info/parser.js +116 -35
  338. package/test/unit/spec/locus-info/selfConstant.js +27 -4
  339. package/test/unit/spec/locus-info/selfUtils.js +208 -17
  340. package/test/unit/spec/media/index.ts +120 -37
  341. package/test/unit/spec/media/properties.ts +2 -2
  342. package/test/unit/spec/meeting/in-meeting-actions.ts +85 -3
  343. package/test/unit/spec/meeting/index.js +5849 -2014
  344. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  345. package/test/unit/spec/meeting/muteState.js +402 -213
  346. package/test/unit/spec/meeting/request.js +483 -49
  347. package/test/unit/spec/meeting/utils.js +679 -64
  348. package/test/unit/spec/meeting-info/index.js +300 -0
  349. package/test/unit/spec/meeting-info/meetinginfov2.js +526 -5
  350. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  351. package/test/unit/spec/meetings/collection.js +26 -0
  352. package/test/unit/spec/meetings/index.js +1231 -212
  353. package/test/unit/spec/meetings/utils.js +202 -2
  354. package/test/unit/spec/member/index.js +61 -6
  355. package/test/unit/spec/member/util.js +510 -34
  356. package/test/unit/spec/members/index.js +432 -1
  357. package/test/unit/spec/members/request.js +206 -27
  358. package/test/unit/spec/members/utils.js +210 -0
  359. package/test/unit/spec/metrics/index.js +1 -50
  360. package/test/unit/spec/multistream/mediaRequestManager.ts +776 -162
  361. package/test/unit/spec/multistream/receiveSlot.ts +28 -20
  362. package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
  363. package/test/unit/spec/multistream/remoteMedia.ts +30 -0
  364. package/test/unit/spec/multistream/remoteMediaGroup.ts +266 -0
  365. package/test/unit/spec/multistream/remoteMediaManager.ts +326 -0
  366. package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
  367. package/test/unit/spec/reachability/clusterReachability.ts +279 -0
  368. package/test/unit/spec/reachability/index.ts +486 -13
  369. package/test/unit/spec/reachability/request.js +68 -0
  370. package/test/unit/spec/reachability/util.ts +40 -0
  371. package/test/unit/spec/reconnection-manager/index.js +117 -11
  372. package/test/unit/spec/recording-controller/index.js +294 -218
  373. package/test/unit/spec/recording-controller/util.js +223 -96
  374. package/test/unit/spec/roap/index.ts +174 -63
  375. package/test/unit/spec/roap/request.ts +226 -85
  376. package/test/unit/spec/roap/turnDiscovery.ts +76 -34
  377. package/test/unit/spec/rtcMetrics/index.ts +93 -0
  378. package/test/unit/spec/stats-analyzer/index.js +231 -7
  379. package/test/unit/spec/webinar/collection.ts +13 -0
  380. package/test/unit/spec/webinar/index.ts +60 -0
  381. package/test/utils/integrationTestUtils.js +46 -0
  382. package/test/utils/testUtils.js +0 -52
  383. package/dist/meeting/effectsState.js +0 -262
  384. package/dist/meeting/effectsState.js.map +0 -1
  385. package/dist/metrics/config.js +0 -289
  386. package/dist/metrics/config.js.map +0 -1
  387. package/dist/types/meeting/effectsState.d.ts +0 -42
  388. package/dist/types/metrics/config.d.ts +0 -169
  389. package/src/index.js +0 -16
  390. package/src/meeting/effectsState.ts +0 -211
  391. package/src/metrics/config.ts +0 -485
  392. package/test/unit/spec/meeting/effectsState.js +0 -285
@@ -1,102 +1,229 @@
1
1
  import RecordingUtil from '@webex/plugin-meetings/src/recording-controller/util';
2
2
  import RecordingAction from '@webex/plugin-meetings/src/recording-controller/enums';
3
- import { assert } from 'chai';
3
+ import {SELF_POLICY} from '@webex/plugin-meetings/src/constants';
4
+
5
+ import {assert} from 'chai';
4
6
 
5
7
  describe('plugin-meetings', () => {
6
- describe('recording-controller tests', () => {
7
- describe('recording util tests', () => {
8
-
9
- let locusInfo;
10
-
11
- beforeEach(() => {
12
- locusInfo = {
13
- parsedLocus: {
14
- info: {
15
- userDisplayHints: [],
16
- },
17
- },
18
- };
19
- });
20
-
21
- describe('canUserStart', () => {
22
- it('can start recording when the correct display hint is present', () => {
23
- locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_START');
24
-
25
- assert.equal(RecordingUtil.canUserStart(locusInfo.parsedLocus.info.userDisplayHints), true);
26
- });
27
-
28
- it('rejects when correct display hint is not present', () => {
29
- assert.equal(RecordingUtil.canUserStart(locusInfo.parsedLocus.info.userDisplayHints), false);
30
- });
31
- });
32
-
33
- describe('canUserPause', () => {
34
- it('can pause recording when the correct display hint is present', () => {
35
- locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_PAUSE');
36
-
37
- assert.equal(RecordingUtil.canUserPause(locusInfo.parsedLocus.info.userDisplayHints), true);
38
- });
39
-
40
- it('rejects when correct display hint is not present', () => {
41
- assert.equal(RecordingUtil.canUserPause(locusInfo.parsedLocus.info.userDisplayHints), false);
42
- });
43
- });
44
-
45
- describe('canUserStop', () => {
46
- it('can stop recording when the correct display hint is present', () => {
47
- locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_STOP');
48
-
49
- assert.equal(RecordingUtil.canUserStop(locusInfo.parsedLocus.info.userDisplayHints), true);
50
- });
51
-
52
- it('rejects when correct display hint is not present', () => {
53
- assert.equal(RecordingUtil.canUserStop(locusInfo.parsedLocus.info.userDisplayHints), false);
54
- });
55
- });
56
-
57
- describe('canUserResume', () => {
58
- it('can start recording when the correct display hint is present', () => {
59
- locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_RESUME');
60
-
61
- assert.equal(RecordingUtil.canUserResume(locusInfo.parsedLocus.info.userDisplayHints), true);
62
- });
63
-
64
- it('rejects when correct display hint is not present', () => {
65
- assert.equal(RecordingUtil.canUserResume(locusInfo.parsedLocus.info.userDisplayHints), false);
66
- });
67
- });
68
-
69
- describe('deriveRecordingStates', () => {
70
- it('gets the correct values for a start recording action', () => {
71
- assert.deepEqual(RecordingUtil.deriveRecordingStates(RecordingAction.Start), {recording: true, paused: false});
72
- });
73
-
74
- it('gets the correct values for a stop recording action', () => {
75
- assert.deepEqual(RecordingUtil.deriveRecordingStates(RecordingAction.Stop), {recording: false, paused: false});
76
- });
77
-
78
- it('gets the correct values for a resume recording action', () => {
79
- assert.deepEqual(RecordingUtil.deriveRecordingStates(RecordingAction.Resume), {recording: true, paused: false});
80
- });
81
-
82
- it('gets the correct values for a paused recording action', () => {
83
- assert.deepEqual(RecordingUtil.deriveRecordingStates(RecordingAction.Pause), {recording: true, paused: true});
84
- });
85
- });
86
-
87
- describe('extractLocusId', () => {
88
- it('gets the correct id from the url param', () => {
89
- assert.equal(RecordingUtil.extractLocusId('test/id'), 'id');
90
- });
91
-
92
- it('works with empty string parameters passed', () => {
93
- assert.equal(RecordingUtil.extractLocusId(''), '');
94
- });
95
-
96
- it('works with no parameters passed', () => {
97
- assert.isUndefined(RecordingUtil.extractLocusId(undefined));
98
- });
99
- });
8
+ describe('recording-controller tests', () => {
9
+ describe('recording util tests', () => {
10
+ let locusInfo;
11
+
12
+ beforeEach(() => {
13
+ locusInfo = {
14
+ parsedLocus: {
15
+ info: {
16
+ userDisplayHints: [],
17
+ },
18
+ },
19
+ };
20
+ });
21
+
22
+ describe('canUserStart', () => {
23
+ it('can start recording when the correct display hint is present', () => {
24
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_START');
25
+
26
+ assert.equal(
27
+ RecordingUtil.canUserStart(locusInfo.parsedLocus.info.userDisplayHints),
28
+ true
29
+ );
30
+ });
31
+
32
+ it('can start recording when the correct display hint is present and the policy is true', () => {
33
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_START');
34
+
35
+ assert.equal(
36
+ RecordingUtil.canUserStart(locusInfo.parsedLocus.info.userDisplayHints, {
37
+ [SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD]: true,
38
+ }),
39
+ true
40
+ );
41
+ });
42
+
43
+ it('rejects when correct display hint is not present', () => {
44
+ assert.equal(
45
+ RecordingUtil.canUserStart(locusInfo.parsedLocus.info.userDisplayHints),
46
+ false
47
+ );
48
+ });
49
+
50
+ it('rejects when correct display hint is present but policy is false', () => {
51
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_START');
52
+
53
+ assert.equal(
54
+ RecordingUtil.canUserStart(locusInfo.parsedLocus.info.userDisplayHints, {
55
+ [SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD]: false,
56
+ }),
57
+ false
58
+ );
59
+ });
60
+ });
61
+
62
+ describe('canUserPause', () => {
63
+ it('can pause recording when the correct display hint is present', () => {
64
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_PAUSE');
65
+
66
+ assert.equal(
67
+ RecordingUtil.canUserPause(locusInfo.parsedLocus.info.userDisplayHints),
68
+ true
69
+ );
70
+ });
71
+
72
+ it('can pause recording when the correct display hint is present and the policy is true', () => {
73
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_PAUSE');
74
+
75
+ assert.equal(
76
+ RecordingUtil.canUserPause(locusInfo.parsedLocus.info.userDisplayHints, {
77
+ [SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD]: true,
78
+ }),
79
+ true
80
+ );
81
+ });
82
+
83
+ it('rejects when correct display hint is not present', () => {
84
+ assert.equal(
85
+ RecordingUtil.canUserPause(locusInfo.parsedLocus.info.userDisplayHints),
86
+ false
87
+ );
88
+ });
89
+
90
+ it('rejects when correct display hint is present but the policy is false', () => {
91
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_PAUSE');
92
+
93
+ assert.equal(
94
+ RecordingUtil.canUserPause(locusInfo.parsedLocus.info.userDisplayHints, {
95
+ [SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD]: false,
96
+ }),
97
+ false
98
+ );
99
+ });
100
+ });
101
+
102
+ describe('canUserStop', () => {
103
+ it('can stop recording when the correct display hint is present', () => {
104
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_STOP');
105
+
106
+ assert.equal(
107
+ RecordingUtil.canUserStop(locusInfo.parsedLocus.info.userDisplayHints),
108
+ true
109
+ );
110
+ });
111
+
112
+ it('can stop recording when the correct display hint is present and the policy is true', () => {
113
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_STOP', {
114
+ [SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD]: true,
115
+ });
116
+
117
+ assert.equal(
118
+ RecordingUtil.canUserStop(locusInfo.parsedLocus.info.userDisplayHints),
119
+ true
120
+ );
121
+ });
122
+
123
+ it('rejects when correct display hint is not present', () => {
124
+ assert.equal(
125
+ RecordingUtil.canUserStop(locusInfo.parsedLocus.info.userDisplayHints),
126
+ false
127
+ );
128
+ });
129
+
130
+ it('rejects when correct display hint is present but the policy is false', () => {
131
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_STOP', {
132
+ [SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD]: true,
133
+ });
134
+
135
+ assert.equal(
136
+ RecordingUtil.canUserStop(locusInfo.parsedLocus.info.userDisplayHints, {
137
+ [SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD]: false,
138
+ }),
139
+ false
140
+ );
141
+ });
142
+ });
143
+
144
+ describe('canUserResume', () => {
145
+ it('can start recording when the correct display hint is present', () => {
146
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_RESUME');
147
+
148
+ assert.equal(
149
+ RecordingUtil.canUserResume(locusInfo.parsedLocus.info.userDisplayHints),
150
+ true
151
+ );
152
+ });
153
+
154
+ it('can start recording when the correct display hint is present and the policy is true', () => {
155
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_RESUME');
156
+
157
+ assert.equal(
158
+ RecordingUtil.canUserResume(locusInfo.parsedLocus.info.userDisplayHints, {
159
+ [SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD]: true,
160
+ }),
161
+ true
162
+ );
163
+ });
164
+
165
+ it('rejects when correct display hint is not present', () => {
166
+ assert.equal(
167
+ RecordingUtil.canUserResume(locusInfo.parsedLocus.info.userDisplayHints),
168
+ false
169
+ );
170
+ });
171
+
172
+ it('rejects when correct display hint is present but the policy is false', () => {
173
+ locusInfo.parsedLocus.info.userDisplayHints.push('RECORDING_CONTROL_RESUME');
174
+
175
+ assert.equal(
176
+ RecordingUtil.canUserResume(locusInfo.parsedLocus.info.userDisplayHints, {
177
+ [SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD]: false,
178
+ }),
179
+ false
180
+ );
181
+ });
182
+ });
183
+
184
+ describe('deriveRecordingStates', () => {
185
+ it('gets the correct values for a start recording action', () => {
186
+ assert.deepEqual(RecordingUtil.deriveRecordingStates(RecordingAction.Start), {
187
+ recording: true,
188
+ paused: false,
189
+ });
190
+ });
191
+
192
+ it('gets the correct values for a stop recording action', () => {
193
+ assert.deepEqual(RecordingUtil.deriveRecordingStates(RecordingAction.Stop), {
194
+ recording: false,
195
+ paused: false,
196
+ });
197
+ });
198
+
199
+ it('gets the correct values for a resume recording action', () => {
200
+ assert.deepEqual(RecordingUtil.deriveRecordingStates(RecordingAction.Resume), {
201
+ recording: true,
202
+ paused: false,
203
+ });
204
+ });
205
+
206
+ it('gets the correct values for a paused recording action', () => {
207
+ assert.deepEqual(RecordingUtil.deriveRecordingStates(RecordingAction.Pause), {
208
+ recording: true,
209
+ paused: true,
210
+ });
211
+ });
212
+ });
213
+
214
+ describe('extractLocusId', () => {
215
+ it('gets the correct id from the url param', () => {
216
+ assert.equal(RecordingUtil.extractLocusId('test/id'), 'id');
217
+ });
218
+
219
+ it('works with empty string parameters passed', () => {
220
+ assert.equal(RecordingUtil.extractLocusId(''), '');
221
+ });
222
+
223
+ it('works with no parameters passed', () => {
224
+ assert.isUndefined(RecordingUtil.extractLocusId(undefined));
100
225
  });
226
+ });
101
227
  });
102
- });
228
+ });
229
+ });
@@ -1,38 +1,41 @@
1
1
  import {assert} from '@webex/test-helper-chai';
2
2
  import sinon from 'sinon';
3
3
  import TurnDiscovery from '@webex/plugin-meetings/src/roap/turnDiscovery';
4
+ import MockWebex from '@webex/test-helper-mock-webex';
4
5
 
5
6
  import RoapRequest from '@webex/plugin-meetings/src/roap/request';
6
7
  import Roap from '@webex/plugin-meetings/src/roap/';
7
8
  import Meeting from '@webex/plugin-meetings/src/meeting';
9
+ import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
10
+ import Metrics from '@webex/plugin-meetings/src/metrics';
11
+ import BEHAVIORAL_METRICS from '@webex/plugin-meetings/src/metrics/constants';
12
+
13
+ import { IP_VERSION } from '../../../../src/constants';
8
14
 
9
15
  describe('Roap', () => {
10
16
  describe('doTurnDiscovery', () => {
11
- it('calls this.turnDiscovery.doTurnDiscovery() and forwards all the arguments', async () => {
12
- const RESULT = {something: 'some value'};
13
- const meeting = {id: 'some meeting id'} as Meeting;
14
-
15
- const doTurnDiscoveryStub = sinon
16
- .stub(TurnDiscovery.prototype, 'doTurnDiscovery')
17
- .resolves(RESULT);
18
-
19
- const roap = new Roap({}, {parent: 'fake'});
17
+ [false, true].forEach(function (isReconnecting) {
18
+ [false, true, undefined].forEach(function (isForced) {
19
+ it(`calls this.turnDiscovery.doTurnDiscovery() and forwards all the arguments when isReconnecting = ${isReconnecting} and isForced = ${isForced}`, async () => {
20
+ const webex = new MockWebex({});
20
21
 
21
- // call with isReconnecting: true
22
- const result = await roap.doTurnDiscovery(meeting, true);
22
+ const RESULT = {something: 'some value'};
23
+ const meeting = {id: 'some meeting id'} as Meeting;
23
24
 
24
- assert.calledOnceWithExactly(doTurnDiscoveryStub, meeting, true);
25
- assert.deepEqual(result, RESULT);
25
+ const doTurnDiscoveryStub = sinon
26
+ .stub(TurnDiscovery.prototype, 'doTurnDiscovery')
27
+ .resolves(RESULT);
26
28
 
27
- doTurnDiscoveryStub.resetHistory();
29
+ const roap = new Roap({}, {parent: webex});
28
30
 
29
- // and with isReconnecting: false
30
- const result2 = await roap.doTurnDiscovery(meeting, false);
31
+ const result = await roap.doTurnDiscovery(meeting, isReconnecting, isForced);
31
32
 
32
- assert.calledOnceWithExactly(doTurnDiscoveryStub, meeting, false);
33
- assert.deepEqual(result2, RESULT);
33
+ assert.calledOnceWithExactly(doTurnDiscoveryStub, meeting, isReconnecting, isForced);
34
+ assert.deepEqual(result, RESULT);
34
35
 
35
- sinon.restore();
36
+ sinon.restore();
37
+ });
38
+ });
36
39
  });
37
40
  });
38
41
 
@@ -40,24 +43,39 @@ describe('Roap', () => {
40
43
  let sendRoapStub;
41
44
  let meeting;
42
45
 
46
+ let webex;
47
+ let roap;
48
+
49
+ const fakeLocus = {id: 'fake locus'};
50
+
43
51
  beforeEach(() => {
52
+ webex = new MockWebex({});
44
53
  meeting = {
45
54
  id: 'some meeting id',
46
55
  correlationId: 'correlation id',
47
56
  selfUrl: 'self url',
48
57
  mediaId: 'media id',
49
- audio:{
58
+ audio: {
50
59
  isLocallyMuted: () => true,
51
60
  },
52
- video:{
61
+ video: {
53
62
  isLocallyMuted: () => false,
54
63
  },
64
+ isMultistream: true,
55
65
  setRoapSeq: sinon.stub(),
56
- config: {experimental: {enableTurnDiscovery: false}},
66
+ locusMediaRequest: {fake: true},
67
+ webex: {meetings: {reachability: {isAnyPublicClusterReachable: () => true}}},
68
+ updateMediaConnections: sinon.stub(),
57
69
  };
58
70
 
71
+ sinon.stub(MeetingUtil, 'getIpVersion').returns(IP_VERSION.unknown);
72
+ sinon.stub(Metrics, 'sendBehavioralMetric');
73
+
59
74
  sendRoapStub = sinon.stub(RoapRequest.prototype, 'sendRoap').resolves({});
60
75
  meeting.setRoapSeq.resetHistory();
76
+
77
+ roap = new Roap({}, {parent: webex});
78
+ sinon.stub(roap.turnDiscovery, 'isSkipped').resolves(false);
61
79
  });
62
80
 
63
81
  afterEach(() => {
@@ -65,19 +83,17 @@ describe('Roap', () => {
65
83
  });
66
84
 
67
85
  [
68
- {reconnect: true, enableTurnDiscovery: true, expectEmptyMediaId: false},
69
- {reconnect: true, enableTurnDiscovery: false, expectEmptyMediaId: true},
70
- {reconnect: false, enableTurnDiscovery: true, expectEmptyMediaId: false},
71
- {reconnect: false, enableTurnDiscovery: false, expectEmptyMediaId: false},
72
- ].forEach(({reconnect, enableTurnDiscovery, expectEmptyMediaId}) =>
86
+ {reconnect: true, turnDiscoverySkipped: false, expectEmptyMediaId: false},
87
+ {reconnect: true, turnDiscoverySkipped: true, expectEmptyMediaId: true},
88
+ {reconnect: false, turnDiscoverySkipped: false, expectEmptyMediaId: false},
89
+ {reconnect: false, turnDiscoverySkipped: true, expectEmptyMediaId: false},
90
+ ].forEach(({reconnect, turnDiscoverySkipped, expectEmptyMediaId}) =>
73
91
  it(`sends roap OFFER with ${expectEmptyMediaId ? 'empty ' : ''}mediaId when ${
74
92
  reconnect ? '' : 'not '
75
93
  }reconnecting and TURN discovery is ${
76
- enableTurnDiscovery ? 'enabled' : 'disabled'
94
+ turnDiscoverySkipped ? 'skipped' : 'not skipped'
77
95
  }`, async () => {
78
- meeting.config.experimental.enableTurnDiscovery = enableTurnDiscovery;
79
-
80
- const roap = new Roap({}, {parent: 'fake'});
96
+ roap.turnDiscovery.isSkipped.resolves(turnDiscoverySkipped);
81
97
 
82
98
  await roap.sendRoapMediaRequest({
83
99
  meeting,
@@ -93,53 +109,148 @@ describe('Roap', () => {
93
109
  version: '2',
94
110
  seq: 2,
95
111
  tieBreaker: 4294967294,
112
+ headers: ['includeAnswerInHttpResponse', 'noOkInTransaction'],
96
113
  };
97
114
 
98
115
  assert.calledOnce(sendRoapStub);
99
- assert.calledWith(sendRoapStub, {
100
- roapMessage: expectedRoapMessage,
101
- correlationId: meeting.correlationId,
102
- locusSelfUrl: meeting.selfUrl,
103
- mediaId: expectEmptyMediaId ? '' : meeting.mediaId,
104
- audioMuted: meeting.audio?.isLocallyMuted(),
105
- videoMuted: meeting.video?.isLocallyMuted(),
106
- meetingId: meeting.id,
107
- preferTranscoding: true,
108
- });
116
+ assert.calledWith(
117
+ sendRoapStub,
118
+ sinon.match({
119
+ roapMessage: expectedRoapMessage,
120
+ locusSelfUrl: meeting.selfUrl,
121
+ mediaId: expectEmptyMediaId ? '' : meeting.mediaId,
122
+ meetingId: meeting.id,
123
+ locusMediaRequest: meeting.locusMediaRequest,
124
+ })
125
+ );
109
126
  })
110
127
  );
111
- it('sends roap request with preferTranscoding=false for multistream meetings', async () => {
112
- const roap = new Roap({}, {parent: 'fake'});
113
128
 
114
- meeting.isMultistream = true;
129
+ it('reads SDP answer from the http response', async () => {
130
+ const roapAnswer = {
131
+ seq: 5,
132
+ messageType: 'ANSWER',
133
+ sdps: ['sdp answer'],
134
+ errorType: 'error type', // normally ANSWER would not have errorType or errorCause (only error messages have these)
135
+ errorCause: 'error cause', // but we're just testing here that all the fields are forwarded to the caller of sendRoapMediaRequest()
136
+ headers: ['header1', 'header2'],
137
+ };
138
+ const fakeMediaConnections = [
139
+ {
140
+ remoteSdp: JSON.stringify({
141
+ roapMessage: roapAnswer,
142
+ }),
143
+ },
144
+ ];
115
145
 
116
- await roap.sendRoapMediaRequest({
146
+ sendRoapStub.resolves({
147
+ mediaConnections: fakeMediaConnections,
148
+ locus: fakeLocus,
149
+ });
150
+
151
+ const result = await roap.sendRoapMediaRequest({
117
152
  meeting,
118
153
  sdp: 'sdp',
119
154
  reconnect: false,
120
- seq: 10,
121
- tieBreaker: 1,
155
+ seq: 1,
156
+ tieBreaker: 4294967294,
122
157
  });
123
158
 
124
- const expectedRoapMessage = {
125
- messageType: 'OFFER',
126
- sdps: ['sdp'],
127
- version: '2',
128
- seq: 10,
129
- tieBreaker: 1,
130
- };
159
+ assert.calledOnce(sendRoapStub);
160
+ assert.calledOnceWithExactly(meeting.updateMediaConnections, fakeMediaConnections);
161
+ assert.deepEqual(result, {
162
+ locus: fakeLocus,
163
+ roapAnswer: {
164
+ seq: 5,
165
+ messageType: 'ANSWER',
166
+ sdp: 'sdp answer',
167
+ errorType: 'error type',
168
+ errorCause: 'error cause',
169
+ headers: ['header1', 'header2'],
170
+ },
171
+ });
172
+ });
173
+
174
+ it('handles the case when there is no answer in the http response', async () => {
175
+ const fakeMediaConnections = [
176
+ {
177
+ // this is the actual value Locus returns to us when they don't send Roap ANSWER in the http response
178
+ remoteSdp:
179
+ '{"audioMuted":false,"videoMuted":false,"csis":[],"dtmfReceiveSupported":true,"type":"SDP"}',
180
+ },
181
+ ];
182
+
183
+ sendRoapStub.resolves({
184
+ mediaConnections: fakeMediaConnections,
185
+ locus: fakeLocus,
186
+ });
187
+
188
+ const result = await roap.sendRoapMediaRequest({
189
+ meeting,
190
+ sdp: 'sdp',
191
+ reconnect: false,
192
+ seq: 1,
193
+ tieBreaker: 4294967294,
194
+ });
131
195
 
132
196
  assert.calledOnce(sendRoapStub);
133
- assert.calledWith(sendRoapStub, {
134
- roapMessage: expectedRoapMessage,
135
- correlationId: meeting.correlationId,
136
- locusSelfUrl: meeting.selfUrl,
137
- mediaId: meeting.mediaId,
138
- audioMuted: meeting.audio.isLocallyMuted(),
139
- videoMuted: meeting.video.isLocallyMuted(),
140
- meetingId: meeting.id,
141
- preferTranscoding: false,
197
+ assert.calledOnceWithExactly(meeting.updateMediaConnections, fakeMediaConnections);
198
+ assert.deepEqual(result, {
199
+ locus: fakeLocus,
200
+ roapAnswer: undefined,
142
201
  });
202
+ assert.calledOnceWithExactly(
203
+ Metrics.sendBehavioralMetric,
204
+ BEHAVIORAL_METRICS.ROAP_HTTP_RESPONSE_MISSING,
205
+ {
206
+ correlationId: meeting.correlationId,
207
+ messageType: 'ANSWER',
208
+ isMultistream: meeting.isMultistream,
209
+ }
210
+ );
211
+ });
212
+
213
+ describe('does not crash when http response is missing things', () => {
214
+ [
215
+ {mediaConnections: undefined, title: 'mediaConnections are undefined'},
216
+ {mediaConnections: [], title: 'mediaConnections are empty array'},
217
+ {mediaConnections: [{}], title: 'mediaConnections[0] has no remoteSdp'},
218
+ {
219
+ mediaConnections: [{remoteSdp: '{}'}],
220
+ title: 'mediaConnections[0].remoteSdp is an empty json',
221
+ },
222
+ ].forEach(({mediaConnections, title}) =>
223
+ it(title, async () => {
224
+ sendRoapStub.resolves({
225
+ mediaConnections,
226
+ locus: fakeLocus,
227
+ });
228
+
229
+ const result = await roap.sendRoapMediaRequest({
230
+ meeting,
231
+ sdp: 'sdp',
232
+ reconnect: false,
233
+ seq: 1,
234
+ tieBreaker: 4294967294,
235
+ });
236
+
237
+ assert.calledOnce(sendRoapStub);
238
+ assert.deepEqual(result, {
239
+ locus: fakeLocus,
240
+ roapAnswer: undefined,
241
+ });
242
+
243
+ assert.calledOnceWithExactly(
244
+ Metrics.sendBehavioralMetric,
245
+ BEHAVIORAL_METRICS.ROAP_HTTP_RESPONSE_MISSING,
246
+ {
247
+ correlationId: meeting.correlationId,
248
+ messageType: 'ANSWER',
249
+ isMultistream: meeting.isMultistream,
250
+ }
251
+ );
252
+ })
253
+ );
143
254
  });
144
255
  });
145
256
  });