@webex/plugin-meetings 3.7.0 → 3.8.0

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 (351) hide show
  1. package/dist/annotation/annotation.types.d.ts +42 -0
  2. package/dist/annotation/constants.d.ts +31 -0
  3. package/dist/annotation/index.d.ts +117 -0
  4. package/dist/annotation/index.js +17 -0
  5. package/dist/annotation/index.js.map +1 -1
  6. package/dist/breakouts/breakout.d.ts +8 -0
  7. package/dist/breakouts/breakout.js +1 -1
  8. package/dist/breakouts/collection.d.ts +5 -0
  9. package/dist/breakouts/edit-lock-error.d.ts +15 -0
  10. package/dist/breakouts/events.d.ts +8 -0
  11. package/dist/breakouts/index.d.ts +5 -0
  12. package/dist/breakouts/index.js +1 -1
  13. package/dist/breakouts/request.d.ts +22 -0
  14. package/dist/breakouts/utils.d.ts +15 -0
  15. package/dist/common/browser-detection.d.ts +9 -0
  16. package/dist/common/collection.d.ts +48 -0
  17. package/dist/common/config.d.ts +2 -0
  18. package/dist/common/errors/captcha-error.d.ts +15 -0
  19. package/dist/common/errors/intent-to-join.d.ts +16 -0
  20. package/dist/common/errors/join-forbidden-error.js +52 -0
  21. package/dist/common/errors/join-forbidden-error.js.map +1 -0
  22. package/dist/common/errors/join-meeting.d.ts +17 -0
  23. package/dist/common/errors/{webinar-registration-error.js → join-webinar-error.js} +12 -12
  24. package/dist/common/errors/join-webinar-error.js.map +1 -0
  25. package/dist/common/errors/media.d.ts +15 -0
  26. package/dist/common/errors/multistream-not-supported-error.js +53 -0
  27. package/dist/common/errors/multistream-not-supported-error.js.map +1 -0
  28. package/dist/common/errors/no-meeting-info.d.ts +14 -0
  29. package/dist/common/errors/parameter.d.ts +15 -0
  30. package/dist/common/errors/password-error.d.ts +15 -0
  31. package/dist/common/errors/permission.d.ts +14 -0
  32. package/dist/common/errors/reclaim-host-role-error.js +149 -0
  33. package/dist/common/errors/reclaim-host-role-error.js.map +1 -0
  34. package/dist/common/errors/reclaim-host-role-errors.d.ts +60 -0
  35. package/dist/common/errors/reconnection-in-progress.d.ts +9 -0
  36. package/dist/common/errors/reconnection-in-progress.js +33 -0
  37. package/dist/common/errors/reconnection-in-progress.js.map +1 -0
  38. package/dist/common/errors/reconnection.d.ts +15 -0
  39. package/dist/common/errors/stats.d.ts +15 -0
  40. package/dist/common/errors/webex-errors.d.ts +93 -0
  41. package/dist/common/errors/webex-meetings-error.d.ts +20 -0
  42. package/dist/common/events/events-scope.d.ts +17 -0
  43. package/dist/common/events/events.d.ts +12 -0
  44. package/dist/common/events/trigger-proxy.d.ts +2 -0
  45. package/dist/common/events/util.d.ts +2 -0
  46. package/dist/common/logs/logger-config.d.ts +2 -0
  47. package/dist/common/logs/logger-proxy.d.ts +2 -0
  48. package/dist/common/logs/request.d.ts +36 -0
  49. package/dist/common/queue.d.ts +34 -0
  50. package/dist/config.d.ts +72 -0
  51. package/dist/config.js +2 -1
  52. package/dist/config.js.map +1 -1
  53. package/dist/constants.d.ts +1088 -0
  54. package/dist/constants.js +68 -6
  55. package/dist/constants.js.map +1 -1
  56. package/dist/controls-options-manager/constants.d.ts +4 -0
  57. package/dist/controls-options-manager/enums.d.ts +15 -0
  58. package/dist/controls-options-manager/index.d.ts +136 -0
  59. package/dist/controls-options-manager/types.d.ts +43 -0
  60. package/dist/controls-options-manager/util.d.ts +1 -0
  61. package/dist/index.d.ts +7 -0
  62. package/dist/index.js +16 -11
  63. package/dist/index.js.map +1 -1
  64. package/dist/interceptors/index.d.ts +2 -0
  65. package/dist/interceptors/locusRetry.d.ts +27 -0
  66. package/dist/interpretation/collection.d.ts +5 -0
  67. package/dist/interpretation/index.d.ts +5 -0
  68. package/dist/interpretation/index.js +1 -1
  69. package/dist/interpretation/siLanguage.d.ts +5 -0
  70. package/dist/interpretation/siLanguage.js +1 -1
  71. package/dist/locus-info/controlsUtils.d.ts +2 -0
  72. package/dist/locus-info/embeddedAppsUtils.d.ts +2 -0
  73. package/dist/locus-info/fullState.d.ts +2 -0
  74. package/dist/locus-info/hostUtils.d.ts +2 -0
  75. package/dist/locus-info/index.d.ts +322 -0
  76. package/dist/locus-info/index.js +14 -3
  77. package/dist/locus-info/index.js.map +1 -1
  78. package/dist/locus-info/infoUtils.d.ts +2 -0
  79. package/dist/locus-info/mediaSharesUtils.d.ts +2 -0
  80. package/dist/locus-info/parser.d.ts +272 -0
  81. package/dist/locus-info/selfUtils.d.ts +2 -0
  82. package/dist/locus-info/selfUtils.js +35 -17
  83. package/dist/locus-info/selfUtils.js.map +1 -1
  84. package/dist/media/MediaConnectionAwaiter.js +1 -0
  85. package/dist/media/MediaConnectionAwaiter.js.map +1 -1
  86. package/dist/media/index.d.ts +34 -0
  87. package/dist/media/properties.d.ts +93 -0
  88. package/dist/media/properties.js +30 -16
  89. package/dist/media/properties.js.map +1 -1
  90. package/dist/media/util.d.ts +2 -0
  91. package/dist/mediaQualityMetrics/config.d.ts +241 -0
  92. package/dist/mediaQualityMetrics/config.js +502 -0
  93. package/dist/mediaQualityMetrics/config.js.map +1 -0
  94. package/dist/meeting/brbState.js +167 -0
  95. package/dist/meeting/brbState.js.map +1 -0
  96. package/dist/meeting/effectsState.js +260 -0
  97. package/dist/meeting/effectsState.js.map +1 -0
  98. package/dist/meeting/in-meeting-actions.d.ts +167 -0
  99. package/dist/meeting/in-meeting-actions.js +13 -1
  100. package/dist/meeting/in-meeting-actions.js.map +1 -1
  101. package/dist/meeting/index.d.ts +1825 -0
  102. package/dist/meeting/index.js +1331 -1051
  103. package/dist/meeting/index.js.map +1 -1
  104. package/dist/meeting/locusMediaRequest.d.ts +74 -0
  105. package/dist/meeting/locusMediaRequest.js +11 -6
  106. package/dist/meeting/locusMediaRequest.js.map +1 -1
  107. package/dist/meeting/muteState.d.ts +178 -0
  108. package/dist/meeting/muteState.js +1 -6
  109. package/dist/meeting/muteState.js.map +1 -1
  110. package/dist/meeting/request.d.ts +295 -0
  111. package/dist/meeting/request.js +51 -29
  112. package/dist/meeting/request.js.map +1 -1
  113. package/dist/meeting/request.type.d.ts +11 -0
  114. package/dist/meeting/request.type.js.map +1 -1
  115. package/dist/meeting/state.d.ts +9 -0
  116. package/dist/meeting/util.d.ts +119 -0
  117. package/dist/meeting/util.js +103 -67
  118. package/dist/meeting/util.js.map +1 -1
  119. package/dist/meeting/voicea-meeting.d.ts +16 -0
  120. package/dist/meeting-info/collection.d.ts +20 -0
  121. package/dist/meeting-info/index.d.ts +69 -0
  122. package/dist/meeting-info/meeting-info-v2.d.ts +123 -0
  123. package/dist/meeting-info/meeting-info-v2.js +115 -45
  124. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  125. package/dist/meeting-info/request.d.ts +22 -0
  126. package/dist/meeting-info/util.d.ts +2 -0
  127. package/dist/meeting-info/utilv2.d.ts +2 -0
  128. package/dist/meeting-info/utilv2.js +6 -2
  129. package/dist/meeting-info/utilv2.js.map +1 -1
  130. package/dist/meetings/collection.d.ts +40 -0
  131. package/dist/meetings/index.d.ts +390 -0
  132. package/dist/meetings/index.js +107 -55
  133. package/dist/meetings/index.js.map +1 -1
  134. package/dist/meetings/meetings.types.d.ts +4 -0
  135. package/dist/meetings/meetings.types.js +2 -0
  136. package/dist/meetings/meetings.types.js.map +1 -1
  137. package/dist/meetings/request.d.ts +27 -0
  138. package/dist/meetings/util.d.ts +18 -0
  139. package/dist/meetings/util.js +1 -1
  140. package/dist/meetings/util.js.map +1 -1
  141. package/dist/member/index.d.ts +160 -0
  142. package/dist/member/index.js +9 -0
  143. package/dist/member/index.js.map +1 -1
  144. package/dist/member/member.types.js +17 -0
  145. package/dist/member/member.types.js.map +1 -0
  146. package/dist/member/types.d.ts +32 -0
  147. package/dist/member/types.js.map +1 -1
  148. package/dist/member/util.d.ts +2 -0
  149. package/dist/member/util.js +39 -28
  150. package/dist/member/util.js.map +1 -1
  151. package/dist/members/collection.d.ts +29 -0
  152. package/dist/members/index.d.ts +353 -0
  153. package/dist/members/request.d.ts +114 -0
  154. package/dist/members/types.d.ts +25 -0
  155. package/dist/members/util.d.ts +215 -0
  156. package/dist/members/util.js +4 -2
  157. package/dist/members/util.js.map +1 -1
  158. package/dist/metrics/config.js +276 -0
  159. package/dist/metrics/config.js.map +1 -0
  160. package/dist/metrics/constants.d.ts +70 -0
  161. package/dist/metrics/constants.js +6 -1
  162. package/dist/metrics/constants.js.map +1 -1
  163. package/dist/metrics/index.d.ts +45 -0
  164. package/dist/multistream/mediaRequestManager.d.ts +119 -0
  165. package/dist/multistream/receiveSlot.d.ts +68 -0
  166. package/dist/multistream/receiveSlotManager.d.ts +56 -0
  167. package/dist/multistream/remoteMedia.d.ts +72 -0
  168. package/dist/multistream/remoteMedia.js +30 -15
  169. package/dist/multistream/remoteMedia.js.map +1 -1
  170. package/dist/multistream/remoteMediaGroup.d.ts +49 -0
  171. package/dist/multistream/remoteMediaManager.d.ts +300 -0
  172. package/dist/multistream/sendSlotManager.d.ts +69 -0
  173. package/dist/multistream/sendSlotManager.js +24 -0
  174. package/dist/multistream/sendSlotManager.js.map +1 -1
  175. package/dist/networkQualityMonitor/index.d.ts +70 -0
  176. package/dist/networkQualityMonitor/index.js +13 -19
  177. package/dist/networkQualityMonitor/index.js.map +1 -1
  178. package/dist/peer-connection-manager/index.js +671 -0
  179. package/dist/peer-connection-manager/index.js.map +1 -0
  180. package/dist/peer-connection-manager/util.js +109 -0
  181. package/dist/peer-connection-manager/util.js.map +1 -0
  182. package/dist/personal-meeting-room/index.d.ts +47 -0
  183. package/dist/personal-meeting-room/request.d.ts +14 -0
  184. package/dist/personal-meeting-room/util.d.ts +2 -0
  185. package/dist/reachability/clusterReachability.d.ts +109 -0
  186. package/dist/reachability/clusterReachability.js +12 -15
  187. package/dist/reachability/clusterReachability.js.map +1 -1
  188. package/dist/reachability/index.d.ts +105 -0
  189. package/dist/reachability/index.js +461 -136
  190. package/dist/reachability/index.js.map +1 -1
  191. package/dist/reachability/reachability.types.js +7 -0
  192. package/dist/reachability/reachability.types.js.map +1 -0
  193. package/dist/reachability/request.d.ts +39 -0
  194. package/dist/reachability/request.js +21 -8
  195. package/dist/reachability/request.js.map +1 -1
  196. package/dist/reachability/util.d.ts +8 -0
  197. package/dist/reactions/constants.d.ts +3 -0
  198. package/dist/reactions/reactions.d.ts +4 -0
  199. package/dist/reactions/reactions.type.d.ts +52 -0
  200. package/dist/reconnection-manager/index.d.ts +136 -0
  201. package/dist/recording-controller/enums.d.ts +7 -0
  202. package/dist/recording-controller/enums.js +8 -4
  203. package/dist/recording-controller/enums.js.map +1 -1
  204. package/dist/recording-controller/index.d.ts +207 -0
  205. package/dist/recording-controller/index.js +18 -9
  206. package/dist/recording-controller/index.js.map +1 -1
  207. package/dist/recording-controller/util.d.ts +14 -0
  208. package/dist/recording-controller/util.js +13 -9
  209. package/dist/recording-controller/util.js.map +1 -1
  210. package/dist/roap/collection.js +62 -0
  211. package/dist/roap/collection.js.map +1 -0
  212. package/dist/roap/handler.js +275 -0
  213. package/dist/roap/handler.js.map +1 -0
  214. package/dist/roap/index.d.ts +86 -0
  215. package/dist/roap/index.js +15 -15
  216. package/dist/roap/index.js.map +1 -1
  217. package/dist/roap/request.d.ts +39 -0
  218. package/dist/roap/request.js +45 -79
  219. package/dist/roap/request.js.map +1 -1
  220. package/dist/roap/state.js +126 -0
  221. package/dist/roap/state.js.map +1 -0
  222. package/dist/roap/turnDiscovery.d.ts +155 -0
  223. package/dist/roap/turnDiscovery.js +3 -6
  224. package/dist/roap/turnDiscovery.js.map +1 -1
  225. package/dist/roap/util.js +75 -0
  226. package/dist/roap/util.js.map +1 -0
  227. package/dist/rtcMetrics/constants.d.ts +4 -0
  228. package/dist/rtcMetrics/index.d.ts +61 -0
  229. package/dist/statsAnalyzer/global.d.ts +36 -0
  230. package/dist/statsAnalyzer/global.js +126 -0
  231. package/dist/statsAnalyzer/global.js.map +1 -0
  232. package/dist/statsAnalyzer/index.d.ts +217 -0
  233. package/dist/statsAnalyzer/index.js +1013 -0
  234. package/dist/statsAnalyzer/index.js.map +1 -0
  235. package/dist/statsAnalyzer/mqaUtil.d.ts +48 -0
  236. package/dist/statsAnalyzer/mqaUtil.js +179 -0
  237. package/dist/statsAnalyzer/mqaUtil.js.map +1 -0
  238. package/dist/transcription/index.d.ts +64 -0
  239. package/dist/types/annotation/index.d.ts +5 -0
  240. package/dist/types/common/errors/join-forbidden-error.d.ts +15 -0
  241. package/dist/types/common/errors/{webinar-registration-error.d.ts → join-webinar-error.d.ts} +2 -2
  242. package/dist/types/common/errors/multistream-not-supported-error.d.ts +17 -0
  243. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  244. package/dist/types/config.d.ts +1 -0
  245. package/dist/types/constants.d.ts +53 -1
  246. package/dist/types/index.d.ts +3 -3
  247. package/dist/types/locus-info/index.d.ts +2 -1
  248. package/dist/types/mediaQualityMetrics/config.d.ts +241 -0
  249. package/dist/types/meeting/brbState.d.ts +54 -0
  250. package/dist/types/meeting/in-meeting-actions.d.ts +12 -0
  251. package/dist/types/meeting/index.d.ts +64 -14
  252. package/dist/types/meeting/locusMediaRequest.d.ts +6 -3
  253. package/dist/types/meeting/request.d.ts +14 -3
  254. package/dist/types/meeting/request.type.d.ts +6 -0
  255. package/dist/types/meeting/util.d.ts +3 -3
  256. package/dist/types/meeting-info/meeting-info-v2.d.ts +30 -5
  257. package/dist/types/meetings/index.d.ts +20 -2
  258. package/dist/types/meetings/meetings.types.d.ts +8 -0
  259. package/dist/types/member/index.d.ts +1 -0
  260. package/dist/types/member/types.d.ts +7 -0
  261. package/dist/types/members/util.d.ts +2 -0
  262. package/dist/types/metrics/constants.d.ts +6 -1
  263. package/dist/types/multistream/sendSlotManager.d.ts +8 -1
  264. package/dist/types/reachability/clusterReachability.d.ts +1 -10
  265. package/dist/types/reachability/index.d.ts +83 -36
  266. package/dist/types/reachability/reachability.types.d.ts +64 -0
  267. package/dist/types/reachability/request.d.ts +5 -1
  268. package/dist/types/recording-controller/enums.d.ts +5 -2
  269. package/dist/types/recording-controller/index.d.ts +1 -0
  270. package/dist/types/recording-controller/util.d.ts +2 -1
  271. package/dist/types/roap/request.d.ts +1 -13
  272. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  273. package/dist/types/statsAnalyzer/index.d.ts +217 -0
  274. package/dist/types/statsAnalyzer/mqaUtil.d.ts +48 -0
  275. package/dist/webinar/collection.d.ts +16 -0
  276. package/dist/webinar/index.d.ts +5 -0
  277. package/dist/webinar/index.js +390 -7
  278. package/dist/webinar/index.js.map +1 -1
  279. package/package.json +23 -22
  280. package/src/annotation/index.ts +16 -0
  281. package/src/common/errors/join-forbidden-error.ts +26 -0
  282. package/src/common/errors/join-webinar-error.ts +24 -0
  283. package/src/common/errors/multistream-not-supported-error.ts +30 -0
  284. package/src/config.ts +1 -0
  285. package/src/constants.ts +61 -3
  286. package/src/index.ts +5 -3
  287. package/src/locus-info/index.ts +20 -3
  288. package/src/locus-info/selfUtils.ts +24 -6
  289. package/src/media/MediaConnectionAwaiter.ts +2 -0
  290. package/src/media/properties.ts +34 -13
  291. package/src/meeting/brbState.ts +169 -0
  292. package/src/meeting/in-meeting-actions.ts +25 -0
  293. package/src/meeting/index.ts +443 -87
  294. package/src/meeting/locusMediaRequest.ts +11 -8
  295. package/src/meeting/muteState.ts +1 -6
  296. package/src/meeting/request.ts +30 -12
  297. package/src/meeting/request.type.ts +7 -0
  298. package/src/meeting/util.ts +32 -13
  299. package/src/meeting-info/meeting-info-v2.ts +83 -12
  300. package/src/meeting-info/utilv2.ts +17 -3
  301. package/src/meetings/index.ts +79 -20
  302. package/src/meetings/meetings.types.ts +10 -0
  303. package/src/meetings/util.ts +2 -1
  304. package/src/member/index.ts +9 -0
  305. package/src/member/types.ts +8 -0
  306. package/src/member/util.ts +34 -24
  307. package/src/members/util.ts +1 -0
  308. package/src/metrics/constants.ts +6 -1
  309. package/src/multistream/remoteMedia.ts +28 -15
  310. package/src/multistream/sendSlotManager.ts +31 -0
  311. package/src/reachability/clusterReachability.ts +5 -15
  312. package/src/reachability/index.ts +311 -75
  313. package/src/reachability/reachability.types.ts +85 -0
  314. package/src/reachability/request.ts +55 -31
  315. package/src/recording-controller/enums.ts +5 -2
  316. package/src/recording-controller/index.ts +17 -4
  317. package/src/recording-controller/util.ts +20 -5
  318. package/src/roap/index.ts +14 -13
  319. package/src/roap/request.ts +30 -44
  320. package/src/roap/turnDiscovery.ts +2 -4
  321. package/src/webinar/index.ts +235 -9
  322. package/test/unit/spec/annotation/index.ts +46 -1
  323. package/test/unit/spec/locus-info/index.js +292 -60
  324. package/test/unit/spec/locus-info/selfConstant.js +7 -0
  325. package/test/unit/spec/locus-info/selfUtils.js +101 -1
  326. package/test/unit/spec/media/properties.ts +15 -0
  327. package/test/unit/spec/meeting/brbState.ts +114 -0
  328. package/test/unit/spec/meeting/in-meeting-actions.ts +15 -1
  329. package/test/unit/spec/meeting/index.js +851 -107
  330. package/test/unit/spec/meeting/locusMediaRequest.ts +18 -11
  331. package/test/unit/spec/meeting/muteState.js +0 -24
  332. package/test/unit/spec/meeting/request.js +3 -26
  333. package/test/unit/spec/meeting/utils.js +73 -28
  334. package/test/unit/spec/meeting-info/meetinginfov2.js +46 -4
  335. package/test/unit/spec/meeting-info/utilv2.js +26 -0
  336. package/test/unit/spec/meetings/index.js +159 -18
  337. package/test/unit/spec/meetings/utils.js +10 -0
  338. package/test/unit/spec/member/util.js +52 -11
  339. package/test/unit/spec/members/utils.js +95 -0
  340. package/test/unit/spec/multistream/remoteMedia.ts +11 -7
  341. package/test/unit/spec/reachability/clusterReachability.ts +7 -0
  342. package/test/unit/spec/reachability/index.ts +383 -9
  343. package/test/unit/spec/reachability/request.js +48 -12
  344. package/test/unit/spec/recording-controller/index.js +61 -5
  345. package/test/unit/spec/recording-controller/util.js +39 -3
  346. package/test/unit/spec/roap/index.ts +48 -1
  347. package/test/unit/spec/roap/request.ts +51 -109
  348. package/test/unit/spec/roap/turnDiscovery.ts +202 -147
  349. package/test/unit/spec/webinar/index.ts +504 -0
  350. package/dist/common/errors/webinar-registration-error.js.map +0 -1
  351. package/src/common/errors/webinar-registration-error.ts +0 -27
@@ -1050,6 +1050,7 @@ describe('gatherReachability', () => {
1050
1050
 
1051
1051
  // the metrics related to ipver and trigger are not tested in these tests and are all the same, so setting them up here
1052
1052
  const expectedMetricsFull = {
1053
+ aborted: false,
1053
1054
  ...expectedMetrics,
1054
1055
  ipver_firstIpV4: -1,
1055
1056
  ipver_firstIpV6: -1,
@@ -1238,6 +1239,7 @@ describe('gatherReachability', () => {
1238
1239
 
1239
1240
  // finally, check the metrics - they should contain values from ipNetworkDetector
1240
1241
  assert.calledWith(Metrics.sendBehavioralMetric, 'js_sdk_reachability_completed', {
1242
+ aborted: false,
1241
1243
  vmn_udp_min: -1,
1242
1244
  vmn_udp_max: -1,
1243
1245
  vmn_udp_average: -1,
@@ -1622,14 +1624,14 @@ describe('gatherReachability', () => {
1622
1624
  const reachability = new Reachability(webex);
1623
1625
 
1624
1626
  let getClustersCallCount = 0;
1625
-
1627
+
1626
1628
  reachability.reachabilityRequest.getClusters = sinon.stub().callsFake(() => {
1627
1629
  getClustersCallCount++;
1628
1630
 
1629
1631
  if (getClustersCallCount == 1) {
1630
1632
  throw new Error('fake error');
1631
1633
  }
1632
-
1634
+
1633
1635
  return getClustersResult;
1634
1636
  });
1635
1637
 
@@ -1637,7 +1639,7 @@ describe('gatherReachability', () => {
1637
1639
 
1638
1640
  await simulateTimeout();
1639
1641
  await promise;
1640
-
1642
+
1641
1643
  assert.equal(getClustersCallCount, 2);
1642
1644
 
1643
1645
  assert.calledOnce(clusterReachabilityCtorStub);
@@ -1647,7 +1649,7 @@ describe('gatherReachability', () => {
1647
1649
  const reachability = new Reachability(webex);
1648
1650
 
1649
1651
  let getClustersCallCount = 0;
1650
-
1652
+
1651
1653
  reachability.reachabilityRequest.getClusters = sinon.stub().callsFake(() => {
1652
1654
  getClustersCallCount++;
1653
1655
 
@@ -1657,13 +1659,356 @@ describe('gatherReachability', () => {
1657
1659
  const promise = reachability.gatherReachability('test');
1658
1660
 
1659
1661
  await simulateTimeout();
1660
-
1662
+
1661
1663
  await promise;
1662
-
1664
+
1663
1665
  assert.equal(getClustersCallCount, 2);
1664
1666
 
1665
1667
  assert.neverCalledWith(clusterReachabilityCtorStub);
1666
1668
  });
1669
+
1670
+ describe('fallback mechanism and multiple calls to getClusters', () => {
1671
+ let receivedEvents;
1672
+
1673
+ const mockGetClustersEmptyResult = {
1674
+ discoveryOptions: {
1675
+ ['early-call-min-clusters']: 0,
1676
+ ['report-version']: 1,
1677
+ },
1678
+ clusters: {}, // empty cluster list
1679
+ joinCookie: {id: 'cookie'},
1680
+ };
1681
+
1682
+ beforeEach(() => {
1683
+ webex.config.meetings.experimental = {
1684
+ enableTcpReachability: true,
1685
+ enableTlsReachability: true,
1686
+ };
1687
+
1688
+ receivedEvents = {
1689
+ done: 0,
1690
+ };
1691
+ });
1692
+
1693
+ it('keeps retrying if minimum required clusters are not reached', async () => {
1694
+ const reachability = new Reachability(webex);
1695
+
1696
+ reachability.on('reachability:done', () => {
1697
+ receivedEvents.done += 1;
1698
+ });
1699
+
1700
+ const mockGetClustersResult1 = {
1701
+ discoveryOptions: {
1702
+ ['early-call-min-clusters']: 2,
1703
+ ['report-version']: 1,
1704
+ },
1705
+ clusters: {
1706
+ clusterA0: {
1707
+ udp: ['udp-urlA'],
1708
+ tcp: ['tcp-urlA'],
1709
+ xtls: ['xtls-urlA'],
1710
+ isVideoMesh: false,
1711
+ },
1712
+ clusterB0: {
1713
+ udp: ['udp-urlB'],
1714
+ tcp: ['tcp-urlB'],
1715
+ xtls: ['xtls-urlB'],
1716
+ isVideoMesh: false,
1717
+ },
1718
+ },
1719
+ joinCookie: {id: 'cookie1'},
1720
+ };
1721
+ const mockGetClustersResult2 = {
1722
+ discoveryOptions: {
1723
+ ['early-call-min-clusters']: 2,
1724
+ ['report-version']: 1,
1725
+ },
1726
+ clusters: {
1727
+ clusterA1: {
1728
+ udp: ['udp-urlA'],
1729
+ tcp: ['tcp-urlA'],
1730
+ xtls: ['xtls-urlA'],
1731
+ isVideoMesh: false,
1732
+ },
1733
+ clusterB1: {
1734
+ udp: ['udp-urlB'],
1735
+ tcp: ['tcp-urlB'],
1736
+ xtls: ['xtls-urlB'],
1737
+ isVideoMesh: false,
1738
+ },
1739
+ },
1740
+ joinCookie: {id: 'cookie2'},
1741
+ };
1742
+ const mockGetClustersResult3 = {
1743
+ discoveryOptions: {
1744
+ ['early-call-min-clusters']: 1,
1745
+ ['report-version']: 1,
1746
+ },
1747
+ clusters: {
1748
+ clusterA2: {
1749
+ udp: ['udp-urlA'],
1750
+ tcp: ['tcp-urlA'],
1751
+ xtls: ['xtls-urlA'],
1752
+ isVideoMesh: false,
1753
+ },
1754
+ clusterB2: {
1755
+ udp: ['udp-urlB'],
1756
+ tcp: ['tcp-urlB'],
1757
+ xtls: ['xtls-urlB'],
1758
+ isVideoMesh: false,
1759
+ },
1760
+ },
1761
+ joinCookie: {id: 'cookie3'},
1762
+ };
1763
+
1764
+ reachability.reachabilityRequest.getClusters = sinon.stub();
1765
+ reachability.reachabilityRequest.getClusters.onCall(0).returns(mockGetClustersResult1);
1766
+ reachability.reachabilityRequest.getClusters.onCall(1).returns(mockGetClustersResult2);
1767
+
1768
+ reachability.reachabilityRequest.getClusters.onCall(2).returns(mockGetClustersResult3);
1769
+
1770
+ const resultPromise = reachability.gatherReachability('test');
1771
+
1772
+ await testUtils.flushPromises();
1773
+
1774
+ // trigger some mock result events from ClusterReachability instances,
1775
+ // but only from 1 cluster, so not enough to reach the minimum required
1776
+ mockClusterReachabilityInstances['clusterA0'].emitFakeResult('udp', {
1777
+ result: 'reachable',
1778
+ clientMediaIPs: ['1.2.3.4'],
1779
+ latencyInMilliseconds: 11,
1780
+ });
1781
+
1782
+ clock.tick(3000);
1783
+ await resultPromise;
1784
+ await testUtils.flushPromises();
1785
+
1786
+ // because the minimum was not reached, another call to getClusters should be made
1787
+ assert.calledTwice(reachability.reachabilityRequest.getClusters);
1788
+
1789
+ // simulate no results this time
1790
+
1791
+ // check that while the 2nd attempt is in progress, the join cookie is already available from the 2nd call to getClusters
1792
+ const clientMediaPreferences = await reachability.getClientMediaPreferences(
1793
+ true,
1794
+ IP_VERSION.unknown
1795
+ );
1796
+
1797
+ assert.deepEqual(clientMediaPreferences.joinCookie, mockGetClustersResult2.joinCookie);
1798
+
1799
+ clock.tick(3000);
1800
+ await testUtils.flushPromises();
1801
+
1802
+ assert.calledThrice(reachability.reachabilityRequest.getClusters);
1803
+
1804
+ await testUtils.flushPromises();
1805
+
1806
+ // this time 1 result will be enough to reach the minimum
1807
+ mockClusterReachabilityInstances['clusterA2'].emitFakeResult('udp', {
1808
+ result: 'reachable',
1809
+ clientMediaIPs: ['1.2.3.4'],
1810
+ latencyInMilliseconds: 11,
1811
+ });
1812
+ clock.tick(3000);
1813
+
1814
+ // the reachability results should include only results from the last attempt
1815
+ await checkResults(
1816
+ {
1817
+ clusterA2: {
1818
+ udp: {result: 'reachable', clientMediaIPs: ['1.2.3.4'], latencyInMilliseconds: 11},
1819
+ tcp: {result: 'unreachable'},
1820
+ xtls: {result: 'unreachable'},
1821
+ isVideoMesh: false,
1822
+ },
1823
+ clusterB2: {
1824
+ udp: {result: 'unreachable'},
1825
+ tcp: {result: 'unreachable'},
1826
+ xtls: {result: 'unreachable'},
1827
+ isVideoMesh: false,
1828
+ },
1829
+ },
1830
+ mockGetClustersResult3.joinCookie
1831
+ );
1832
+
1833
+ // wait some more time to make sure that there are no timers that fire from one of the previous checks
1834
+ clock.tick(20000);
1835
+
1836
+ // as the first 2 attempts failed and didn't reach the overall timeout, there should be only 1 done event emitted
1837
+ assert.equal(receivedEvents.done, 1);
1838
+ });
1839
+
1840
+ it('handles getClusters() returning empty list on 1st call', async () => {
1841
+ const reachability = new Reachability(webex);
1842
+
1843
+ reachability.on('reachability:done', () => {
1844
+ receivedEvents.done += 1;
1845
+ });
1846
+
1847
+ reachability.reachabilityRequest.getClusters = sinon
1848
+ .stub()
1849
+ .resolves(mockGetClustersEmptyResult);
1850
+
1851
+ const resultPromise = reachability.gatherReachability('test');
1852
+
1853
+ await testUtils.flushPromises();
1854
+
1855
+ clock.tick(3000);
1856
+ await resultPromise;
1857
+ await testUtils.flushPromises();
1858
+
1859
+ assert.calledOnce(reachability.reachabilityRequest.getClusters);
1860
+ reachability.reachabilityRequest.getClusters.resetHistory();
1861
+
1862
+ assert.equal(receivedEvents.done, 1);
1863
+ await checkResults({}, mockGetClustersEmptyResult.joinCookie);
1864
+
1865
+ // because we didn't actually test anything (we got empty cluster list from getClusters()), we should
1866
+ // not say that webex backend is unreachable
1867
+ assert.equal(await reachability.isWebexMediaBackendUnreachable(), false);
1868
+
1869
+ // wait to check that there are no other things happening
1870
+ clock.tick(20000);
1871
+ await testUtils.flushPromises();
1872
+
1873
+ assert.notCalled(reachability.reachabilityRequest.getClusters);
1874
+ assert.equal(receivedEvents.done, 1);
1875
+ });
1876
+
1877
+ it('handles getClusters() returning empty list on 2nd call', async () => {
1878
+ const reachability = new Reachability(webex);
1879
+
1880
+ reachability.on('reachability:done', () => {
1881
+ receivedEvents.done += 1;
1882
+ });
1883
+
1884
+ const mockGetClustersResult1 = {
1885
+ discoveryOptions: {
1886
+ ['early-call-min-clusters']: 2,
1887
+ ['report-version']: 1,
1888
+ },
1889
+ clusters: {
1890
+ clusterA0: {
1891
+ udp: ['udp-urlA'],
1892
+ tcp: ['tcp-urlA'],
1893
+ xtls: ['xtls-urlA'],
1894
+ isVideoMesh: false,
1895
+ },
1896
+ clusterB0: {
1897
+ udp: ['udp-urlB'],
1898
+ tcp: ['tcp-urlB'],
1899
+ xtls: ['xtls-urlB'],
1900
+ isVideoMesh: false,
1901
+ },
1902
+ },
1903
+ joinCookie: {id: 'cookie1'},
1904
+ };
1905
+
1906
+ reachability.reachabilityRequest.getClusters = sinon.stub();
1907
+ reachability.reachabilityRequest.getClusters.onCall(0).returns(mockGetClustersResult1);
1908
+ reachability.reachabilityRequest.getClusters.onCall(1).returns(mockGetClustersEmptyResult);
1909
+
1910
+ const resultPromise = reachability.gatherReachability('test');
1911
+
1912
+ await testUtils.flushPromises();
1913
+
1914
+ clock.tick(3000);
1915
+ await resultPromise;
1916
+ await testUtils.flushPromises();
1917
+
1918
+ // because the minimum was not reached, another call to getClusters should be made
1919
+ assert.calledTwice(reachability.reachabilityRequest.getClusters);
1920
+
1921
+ // the reachability results should include only results from the last attempt
1922
+ await checkResults({}, mockGetClustersEmptyResult.joinCookie);
1923
+
1924
+ // as the first 2 attempts failed and didn't reach the overall timeout, there should be only 1 done event emitted
1925
+ assert.equal(receivedEvents.done, 1);
1926
+ // because we didn't actually test anything (we got empty cluster list from getClusters()), we should
1927
+ // not say that webex backend is unreachable
1928
+ assert.equal(await reachability.isWebexMediaBackendUnreachable(), false);
1929
+ });
1930
+ });
1931
+
1932
+ describe('stopReachability', () => {
1933
+ let reachability;
1934
+ let receivedEvents;
1935
+ let sendMetricSpy;
1936
+
1937
+ beforeEach(() => {
1938
+ reachability = new Reachability(webex);
1939
+
1940
+ receivedEvents = {};
1941
+
1942
+ sendMetricSpy = sinon.stub(reachability, 'sendMetric').resolves();
1943
+ });
1944
+
1945
+ const setListener = (event) => {
1946
+ reachability.on(event, () => {
1947
+ receivedEvents[event] = receivedEvents[event] + 1 || 1;
1948
+ });
1949
+ };
1950
+ it('works as expected', async () => {
1951
+ setListener('reachability:stopped');
1952
+ setListener('reachability:done');
1953
+ setListener('reachability:firstResultAvailable');
1954
+
1955
+ const mockGetClustersResult = {
1956
+ clusters: {
1957
+ clusterA: {
1958
+ udp: ['udp-urlA'],
1959
+ tcp: ['tcp-urlA'],
1960
+ xtls: ['xtls-urlA'],
1961
+ isVideoMesh: false,
1962
+ },
1963
+ clusterB: {
1964
+ udp: ['udp-urlB'],
1965
+ tcp: ['tcp-urlB'],
1966
+ xtls: ['xtls-urlB'],
1967
+ isVideoMesh: false,
1968
+ },
1969
+ },
1970
+ joinCookie: {id: 'id'},
1971
+ };
1972
+
1973
+ reachability.reachabilityRequest.getClusters = sinon.stub().returns(mockGetClustersResult);
1974
+
1975
+ const gatherReachabilityFallbackSpy = sinon.spy(reachability, 'gatherReachabilityFallback');
1976
+
1977
+ const resultPromise = reachability.gatherReachability('test');
1978
+
1979
+ await testUtils.flushPromises();
1980
+
1981
+ reachability.stopReachability();
1982
+
1983
+ await resultPromise;
1984
+
1985
+ // simulate a lot of time passing to check that all timers were stopped and nothing else happens
1986
+ clock.tick(99000);
1987
+
1988
+ assert.calledOnceWithExactly(mockClusterReachabilityInstances['clusterA'].abort);
1989
+ assert.calledOnceWithExactly(mockClusterReachabilityInstances['clusterB'].abort);
1990
+
1991
+ assert.calledOnceWithExactly(sendMetricSpy, true);
1992
+
1993
+ assert.equal(receivedEvents['reachability:stopped'], 1);
1994
+ assert.equal(receivedEvents['reachability:done'], undefined);
1995
+ assert.equal(receivedEvents['reachability:firstResultAvailable'], undefined);
1996
+
1997
+ assert.notCalled(gatherReachabilityFallbackSpy);
1998
+ });
1999
+
2000
+ it('does nothing if called without reachability being started', async () => {
2001
+ const reachability = new Reachability(webex);
2002
+
2003
+ reachability.stopReachability();
2004
+
2005
+ assert.notCalled(sendMetricSpy);
2006
+
2007
+ assert.equal(receivedEvents['reachability:stopped'], undefined);
2008
+ assert.equal(receivedEvents['reachability:done'], undefined);
2009
+ assert.equal(receivedEvents['reachability:firstResultAvailable'], undefined);
2010
+ });
2011
+ });
1667
2012
  });
1668
2013
 
1669
2014
  describe('getReachabilityResults', () => {
@@ -2225,19 +2570,18 @@ describe('getStatistics', () => {
2225
2570
  describe('sendMetric', () => {
2226
2571
  let webex;
2227
2572
  let reachability;
2573
+ let getStatisticsStub;
2228
2574
 
2229
2575
  beforeEach(() => {
2230
2576
  webex = new MockWebex();
2231
2577
  reachability = new TestReachability(webex);
2232
2578
 
2233
2579
  sinon.stub(Metrics, 'sendBehavioralMetric');
2234
- });
2235
2580
 
2236
- it('works as expected', async () => {
2237
2581
  // setup stub for getStatistics to return values that show what parameters it was called with,
2238
2582
  // this way we can verify that the correct results of calls to getStatistics are placed
2239
2583
  // in correct data fields when sendBehavioralMetric() is called
2240
- const getStatisticsStub = sinon
2584
+ getStatisticsStub = sinon
2241
2585
  .stub(reachability, 'getStatistics')
2242
2586
  .callsFake((results, protocol, isVideoMesh) => {
2243
2587
  return {result: 'fake', protocol, isVideoMesh};
@@ -2258,7 +2602,13 @@ describe('sendMetric', () => {
2258
2602
  isVideoMesh: false,
2259
2603
  },
2260
2604
  });
2605
+ });
2261
2606
 
2607
+ afterEach(() => {
2608
+ sinon.restore();
2609
+ });
2610
+
2611
+ it('works as expected', async () => {
2262
2612
  await reachability.sendMetric();
2263
2613
 
2264
2614
  // each call to getStatistics should be made with all the results from all fake clusterReachability:
@@ -2282,6 +2632,30 @@ describe('sendMetric', () => {
2282
2632
  assert.alwaysCalledWith(getStatisticsStub, expectedResults, sinon.match.any, sinon.match.any);
2283
2633
 
2284
2634
  assert.calledWith(Metrics.sendBehavioralMetric, 'js_sdk_reachability_completed', {
2635
+ aborted: false,
2636
+ vmn_udp_result: 'fake',
2637
+ vmn_udp_protocol: 'udp',
2638
+ vmn_udp_isVideoMesh: true,
2639
+
2640
+ public_udp_result: 'fake',
2641
+ public_udp_protocol: 'udp',
2642
+ public_udp_isVideoMesh: false,
2643
+
2644
+ public_tcp_result: 'fake',
2645
+ public_tcp_protocol: 'tcp',
2646
+ public_tcp_isVideoMesh: false,
2647
+
2648
+ public_xtls_result: 'fake',
2649
+ public_xtls_protocol: 'xtls',
2650
+ public_xtls_isVideoMesh: false,
2651
+ });
2652
+ });
2653
+
2654
+ it('sends metric with "aborted:true" if called with aborted=true arg', async () => {
2655
+ await reachability.sendMetric(true);
2656
+
2657
+ assert.calledWith(Metrics.sendBehavioralMetric, 'js_sdk_reachability_completed', {
2658
+ aborted: true,
2285
2659
  vmn_udp_result: 'fake',
2286
2660
  vmn_udp_protocol: 'udp',
2287
2661
  vmn_udp_isVideoMesh: true,
@@ -35,16 +35,11 @@ describe('plugin-meetings/reachability', () => {
35
35
  });
36
36
 
37
37
  describe('#getClusters', () => {
38
+ let previousReport;
38
39
 
39
40
  beforeEach(() => {
40
41
  sinon.spy(webex.internal.newMetrics.callDiagnosticLatencies, 'measureLatency');
41
- });
42
-
43
- afterEach(() => {
44
- sinon.restore();
45
- });
46
42
 
47
- it('sends a GET request with the correct params', async () => {
48
43
  webex.request = sinon.mock().returns(Promise.resolve({
49
44
  body: {
50
45
  clusterClasses: {
@@ -59,24 +54,65 @@ describe('plugin-meetings/reachability', () => {
59
54
 
60
55
  webex.config.meetings.reachabilityGetClusterTimeout = 3000;
61
56
 
62
- const res = await reachabilityRequest.getClusters(IP_VERSION.only_ipv4);
57
+ previousReport = {
58
+ id: 'fake previous report',
59
+ }
60
+ });
61
+
62
+ afterEach(() => {
63
+ sinon.restore();
64
+ });
65
+
66
+ it('sends a POST request with the correct params when trigger is "startup"', async () => {
67
+ const res = await reachabilityRequest.getClusters('startup', IP_VERSION.only_ipv4, previousReport);
63
68
  const requestParams = webex.request.getCall(0).args[0];
64
69
 
65
70
  assert.deepEqual(requestParams, {
66
- method: 'GET',
71
+ method: 'POST',
67
72
  resource: `clusters`,
68
73
  api: 'calliopeDiscovery',
69
74
  shouldRefreshAccessToken: false,
70
- qs: {
71
- JCSupport: 1,
72
- ipver: 4,
73
- },
74
75
  timeout: 3000,
76
+ body: {
77
+ ipver: IP_VERSION.only_ipv4,
78
+ 'supported-options': {
79
+ 'report-version': 1,
80
+ 'early-call-min-clusters': true,
81
+ },
82
+ 'previous-report': previousReport,
83
+ trigger: 'startup',
84
+ },
75
85
  });
76
86
 
77
87
  assert.deepEqual(res.clusters.clusterId, {udp: "testUDP", isVideoMesh: true})
78
88
  assert.deepEqual(res.joinCookie, {anycastEntryPoint: "aws-eu-west-1"})
79
89
  assert.calledOnceWithExactly(webex.internal.newMetrics.callDiagnosticLatencies.measureLatency, sinon.match.func, 'internal.get.cluster.time');
80
90
  });
91
+
92
+ it('sends a POST request with the correct params when trigger is other than "startup"', async () => {
93
+ const res = await reachabilityRequest.getClusters('early-call/no-min-reached', IP_VERSION.only_ipv4, previousReport);
94
+ const requestParams = webex.request.getCall(0).args[0];
95
+
96
+ assert.deepEqual(requestParams, {
97
+ method: 'POST',
98
+ resource: `clusters`,
99
+ api: 'calliopeDiscovery',
100
+ shouldRefreshAccessToken: false,
101
+ timeout: 3000,
102
+ body: {
103
+ ipver: IP_VERSION.only_ipv4,
104
+ 'supported-options': {
105
+ 'report-version': 1,
106
+ 'early-call-min-clusters': true,
107
+ },
108
+ 'previous-report': previousReport,
109
+ trigger: 'early-call/no-min-reached',
110
+ },
111
+ });
112
+
113
+ assert.deepEqual(res.clusters.clusterId, {udp: "testUDP", isVideoMesh: true})
114
+ assert.deepEqual(res.joinCookie, {anycastEntryPoint: "aws-eu-west-1"})
115
+ assert.notCalled(webex.internal.newMetrics.callDiagnosticLatencies.measureLatency);
116
+ });
81
117
  });
82
118
  });
@@ -221,7 +221,21 @@ describe('plugin-meetings', () => {
221
221
 
222
222
  assert.calledWith(request.request, {
223
223
  uri: `test/loci/id/recording`,
224
- body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'start'}},
224
+ body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'start'}, recordingType: 'cloud'},
225
+ method: HTTP_VERBS.PUT,
226
+ });
227
+
228
+ assert.deepEqual(result, request.request.firstCall.returnValue);
229
+ });
230
+
231
+ it('can start premise recording when the correct display hint is present', () => {
232
+ controller.setDisplayHints(['PREMISE_RECORDING_CONTROL_START']);
233
+
234
+ const result = controller.startRecording();
235
+
236
+ assert.calledWith(request.request, {
237
+ uri: `test/loci/id/recording`,
238
+ body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'start'}, recordingType: 'premise'},
225
239
  method: HTTP_VERBS.PUT,
226
240
  });
227
241
 
@@ -238,14 +252,28 @@ describe('plugin-meetings', () => {
238
252
  assert.isRejected(result);
239
253
  });
240
254
 
241
- it('can start recording when the correct display hint is present', () => {
255
+ it('can stop recording when the correct display hint is present', () => {
242
256
  controller.setDisplayHints(['RECORDING_CONTROL_STOP']);
243
257
 
244
258
  const result = controller.stopRecording();
245
259
 
246
260
  assert.calledWith(request.request, {
247
261
  uri: `test/loci/id/recording`,
248
- body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'stop'}},
262
+ body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'stop'}, recordingType: 'cloud'},
263
+ method: HTTP_VERBS.PUT,
264
+ });
265
+
266
+ assert.deepEqual(result, request.request.firstCall.returnValue);
267
+ });
268
+
269
+ it('can stop premise recording when the correct display hint is present', () => {
270
+ controller.setDisplayHints(['PREMISE_RECORDING_CONTROL_STOP']);
271
+
272
+ const result = controller.stopRecording();
273
+
274
+ assert.calledWith(request.request, {
275
+ uri: `test/loci/id/recording`,
276
+ body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'stop'}, recordingType: 'premise'},
249
277
  method: HTTP_VERBS.PUT,
250
278
  });
251
279
 
@@ -269,7 +297,21 @@ describe('plugin-meetings', () => {
269
297
 
270
298
  assert.calledWith(request.request, {
271
299
  uri: `test/loci/id/recording`,
272
- body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'pause'}},
300
+ body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'pause'}, recordingType: 'cloud'},
301
+ method: HTTP_VERBS.PUT,
302
+ });
303
+
304
+ assert.deepEqual(result, request.request.firstCall.returnValue);
305
+ });
306
+
307
+ it('can pause premise recording when the correct display hint is present', () => {
308
+ controller.setDisplayHints(['PREMISE_RECORDING_CONTROL_PAUSE']);
309
+
310
+ const result = controller.pauseRecording();
311
+
312
+ assert.calledWith(request.request, {
313
+ uri: `test/loci/id/recording`,
314
+ body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'pause'}, recordingType: 'premise'},
273
315
  method: HTTP_VERBS.PUT,
274
316
  });
275
317
 
@@ -293,7 +335,21 @@ describe('plugin-meetings', () => {
293
335
 
294
336
  assert.calledWith(request.request, {
295
337
  uri: `test/loci/id/recording`,
296
- body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'resume'}},
338
+ body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'resume'}, recordingType: 'cloud'},
339
+ method: HTTP_VERBS.PUT,
340
+ });
341
+
342
+ assert.deepEqual(result, request.request.firstCall.returnValue);
343
+ });
344
+
345
+ it('can resume premise recording when the correct display hint is present', () => {
346
+ controller.setDisplayHints(['PREMISE_RECORDING_CONTROL_RESUME']);
347
+
348
+ const result = controller.resumeRecording();
349
+
350
+ assert.calledWith(request.request, {
351
+ uri: `test/loci/id/recording`,
352
+ body: {meetingInfo: {locusSessionId: 'testId'}, recording: {action: 'resume'}, recordingType: 'premise'},
297
353
  method: HTTP_VERBS.PUT,
298
354
  });
299
355