@webex/plugin-meetings 3.6.0 → 3.7.0-next.10

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 (329) hide show
  1. package/README.md +2 -1
  2. package/dist/breakouts/breakout.js +1 -1
  3. package/dist/breakouts/index.js +1 -1
  4. package/dist/common/errors/webinar-registration-error.js +50 -0
  5. package/dist/common/errors/webinar-registration-error.js.map +1 -0
  6. package/dist/config.js +4 -1
  7. package/dist/config.js.map +1 -1
  8. package/dist/constants.js +40 -2
  9. package/dist/constants.js.map +1 -1
  10. package/dist/controls-options-manager/enums.js +1 -0
  11. package/dist/controls-options-manager/enums.js.map +1 -1
  12. package/dist/controls-options-manager/index.js +10 -3
  13. package/dist/controls-options-manager/index.js.map +1 -1
  14. package/dist/controls-options-manager/types.js.map +1 -1
  15. package/dist/controls-options-manager/util.js +12 -0
  16. package/dist/controls-options-manager/util.js.map +1 -1
  17. package/dist/index.js +7 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/interpretation/index.js +1 -1
  20. package/dist/interpretation/siLanguage.js +1 -1
  21. package/dist/locus-info/controlsUtils.js +28 -4
  22. package/dist/locus-info/controlsUtils.js.map +1 -1
  23. package/dist/locus-info/fullState.js +2 -1
  24. package/dist/locus-info/fullState.js.map +1 -1
  25. package/dist/locus-info/index.js +61 -3
  26. package/dist/locus-info/index.js.map +1 -1
  27. package/dist/locus-info/parser.js +5 -1
  28. package/dist/locus-info/parser.js.map +1 -1
  29. package/dist/meeting/in-meeting-actions.js +29 -1
  30. package/dist/meeting/in-meeting-actions.js.map +1 -1
  31. package/dist/meeting/index.js +786 -528
  32. package/dist/meeting/index.js.map +1 -1
  33. package/dist/meeting/locusMediaRequest.js +2 -6
  34. package/dist/meeting/locusMediaRequest.js.map +1 -1
  35. package/dist/meeting/muteState.js +5 -2
  36. package/dist/meeting/muteState.js.map +1 -1
  37. package/dist/meeting/request.js +21 -29
  38. package/dist/meeting/request.js.map +1 -1
  39. package/dist/meeting/util.js +98 -61
  40. package/dist/meeting/util.js.map +1 -1
  41. package/dist/meeting-info/meeting-info-v2.js +68 -17
  42. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  43. package/dist/meetings/index.js +29 -2
  44. package/dist/meetings/index.js.map +1 -1
  45. package/dist/members/index.js +3 -2
  46. package/dist/members/index.js.map +1 -1
  47. package/dist/members/util.js +13 -7
  48. package/dist/members/util.js.map +1 -1
  49. package/dist/metrics/constants.js +4 -1
  50. package/dist/metrics/constants.js.map +1 -1
  51. package/dist/multistream/remoteMedia.js +4 -0
  52. package/dist/multistream/remoteMedia.js.map +1 -1
  53. package/dist/reachability/clusterReachability.js +12 -15
  54. package/dist/reachability/clusterReachability.js.map +1 -1
  55. package/dist/reachability/index.js +433 -136
  56. package/dist/reachability/index.js.map +1 -1
  57. package/dist/{rtcMetrics/constants.js → reachability/reachability.types.js} +1 -5
  58. package/dist/reachability/reachability.types.js.map +1 -0
  59. package/dist/reachability/request.js +23 -9
  60. package/dist/reachability/request.js.map +1 -1
  61. package/dist/recording-controller/enums.js +8 -4
  62. package/dist/recording-controller/enums.js.map +1 -1
  63. package/dist/recording-controller/index.js +18 -9
  64. package/dist/recording-controller/index.js.map +1 -1
  65. package/dist/recording-controller/util.js +13 -9
  66. package/dist/recording-controller/util.js.map +1 -1
  67. package/dist/roap/index.js +5 -7
  68. package/dist/roap/index.js.map +1 -1
  69. package/dist/roap/request.js +45 -79
  70. package/dist/roap/request.js.map +1 -1
  71. package/dist/roap/turnDiscovery.js +3 -6
  72. package/dist/roap/turnDiscovery.js.map +1 -1
  73. package/dist/{common/errors/parameter.d.ts → types/common/errors/webinar-registration-error.d.ts} +4 -5
  74. package/dist/types/config.d.ts +3 -0
  75. package/dist/types/constants.d.ts +33 -0
  76. package/dist/types/controls-options-manager/enums.d.ts +2 -1
  77. package/dist/types/controls-options-manager/index.d.ts +2 -1
  78. package/dist/types/controls-options-manager/types.d.ts +2 -0
  79. package/dist/types/index.d.ts +2 -1
  80. package/dist/types/locus-info/index.d.ts +9 -0
  81. package/dist/types/meeting/in-meeting-actions.d.ts +28 -0
  82. package/dist/types/meeting/index.d.ts +34 -3
  83. package/dist/types/meeting/locusMediaRequest.d.ts +2 -3
  84. package/dist/types/meeting/muteState.d.ts +2 -1
  85. package/dist/types/meeting/request.d.ts +2 -2
  86. package/dist/types/meeting/util.d.ts +2 -2
  87. package/dist/types/meeting-info/meeting-info-v2.d.ts +23 -0
  88. package/dist/types/meetings/index.d.ts +13 -1
  89. package/dist/types/members/index.d.ts +2 -1
  90. package/dist/types/members/util.d.ts +5 -1
  91. package/dist/types/metrics/constants.d.ts +3 -0
  92. package/dist/types/multistream/remoteMedia.d.ts +1 -0
  93. package/dist/types/reachability/clusterReachability.d.ts +1 -10
  94. package/dist/types/reachability/index.d.ts +74 -35
  95. package/dist/types/reachability/reachability.types.d.ts +64 -0
  96. package/dist/types/reachability/request.d.ts +5 -1
  97. package/dist/types/recording-controller/enums.d.ts +5 -2
  98. package/dist/types/recording-controller/index.d.ts +1 -0
  99. package/dist/types/recording-controller/util.d.ts +2 -1
  100. package/dist/types/roap/request.d.ts +1 -13
  101. package/dist/webinar/index.js +64 -19
  102. package/dist/webinar/index.js.map +1 -1
  103. package/package.json +22 -22
  104. package/src/common/errors/webinar-registration-error.ts +27 -0
  105. package/src/config.ts +3 -0
  106. package/src/constants.ts +41 -0
  107. package/src/controls-options-manager/enums.ts +1 -0
  108. package/src/controls-options-manager/index.ts +19 -2
  109. package/src/controls-options-manager/types.ts +2 -0
  110. package/src/controls-options-manager/util.ts +12 -0
  111. package/src/index.ts +2 -0
  112. package/src/locus-info/controlsUtils.ts +46 -2
  113. package/src/locus-info/fullState.ts +1 -0
  114. package/src/locus-info/index.ts +60 -0
  115. package/src/locus-info/parser.ts +8 -1
  116. package/src/meeting/in-meeting-actions.ts +58 -0
  117. package/src/meeting/index.ts +247 -22
  118. package/src/meeting/locusMediaRequest.ts +4 -8
  119. package/src/meeting/muteState.ts +6 -2
  120. package/src/meeting/request.ts +4 -11
  121. package/src/meeting/util.ts +31 -6
  122. package/src/meeting-info/meeting-info-v2.ts +51 -0
  123. package/src/meetings/index.ts +74 -40
  124. package/src/members/index.ts +4 -2
  125. package/src/members/util.ts +4 -1
  126. package/src/metrics/constants.ts +3 -0
  127. package/src/multistream/remoteMedia.ts +5 -0
  128. package/src/reachability/clusterReachability.ts +5 -15
  129. package/src/reachability/index.ts +285 -77
  130. package/src/reachability/reachability.types.ts +85 -0
  131. package/src/reachability/request.ts +55 -30
  132. package/src/recording-controller/enums.ts +5 -2
  133. package/src/recording-controller/index.ts +17 -4
  134. package/src/recording-controller/util.ts +20 -5
  135. package/src/roap/index.ts +4 -5
  136. package/src/roap/request.ts +32 -44
  137. package/src/roap/turnDiscovery.ts +2 -4
  138. package/src/webinar/index.ts +62 -16
  139. package/test/unit/spec/controls-options-manager/index.js +56 -32
  140. package/test/unit/spec/controls-options-manager/util.js +44 -0
  141. package/test/unit/spec/locus-info/controlsUtils.js +80 -4
  142. package/test/unit/spec/locus-info/index.js +88 -2
  143. package/test/unit/spec/meeting/in-meeting-actions.ts +31 -1
  144. package/test/unit/spec/meeting/index.js +346 -82
  145. package/test/unit/spec/meeting/locusMediaRequest.ts +18 -11
  146. package/test/unit/spec/meeting/muteState.js +8 -4
  147. package/test/unit/spec/meeting/request.js +3 -26
  148. package/test/unit/spec/meeting/utils.js +71 -14
  149. package/test/unit/spec/meeting-info/meetinginfov2.js +37 -0
  150. package/test/unit/spec/meetings/index.js +41 -6
  151. package/test/unit/spec/members/index.js +25 -2
  152. package/test/unit/spec/members/request.js +37 -3
  153. package/test/unit/spec/members/utils.js +110 -1
  154. package/test/unit/spec/multistream/remoteMedia.ts +16 -2
  155. package/test/unit/spec/reachability/clusterReachability.ts +7 -0
  156. package/test/unit/spec/reachability/index.ts +265 -1
  157. package/test/unit/spec/reachability/request.js +56 -15
  158. package/test/unit/spec/recording-controller/index.js +61 -5
  159. package/test/unit/spec/recording-controller/util.js +39 -3
  160. package/test/unit/spec/roap/index.ts +1 -1
  161. package/test/unit/spec/roap/request.ts +51 -109
  162. package/test/unit/spec/roap/turnDiscovery.ts +202 -147
  163. package/test/unit/spec/webinar/index.ts +128 -15
  164. package/dist/annotation/annotation.types.d.ts +0 -42
  165. package/dist/annotation/constants.d.ts +0 -31
  166. package/dist/annotation/index.d.ts +0 -117
  167. package/dist/breakouts/breakout.d.ts +0 -8
  168. package/dist/breakouts/collection.d.ts +0 -5
  169. package/dist/breakouts/edit-lock-error.d.ts +0 -15
  170. package/dist/breakouts/events.d.ts +0 -8
  171. package/dist/breakouts/index.d.ts +0 -5
  172. package/dist/breakouts/request.d.ts +0 -22
  173. package/dist/breakouts/utils.d.ts +0 -15
  174. package/dist/common/browser-detection.d.ts +0 -9
  175. package/dist/common/collection.d.ts +0 -48
  176. package/dist/common/config.d.ts +0 -2
  177. package/dist/common/errors/captcha-error.d.ts +0 -15
  178. package/dist/common/errors/intent-to-join.d.ts +0 -16
  179. package/dist/common/errors/join-meeting.d.ts +0 -17
  180. package/dist/common/errors/media.d.ts +0 -15
  181. package/dist/common/errors/no-meeting-info.d.ts +0 -14
  182. package/dist/common/errors/password-error.d.ts +0 -15
  183. package/dist/common/errors/permission.d.ts +0 -14
  184. package/dist/common/errors/reclaim-host-role-error.js +0 -149
  185. package/dist/common/errors/reclaim-host-role-error.js.map +0 -1
  186. package/dist/common/errors/reclaim-host-role-errors.d.ts +0 -60
  187. package/dist/common/errors/reconnection-in-progress.d.ts +0 -9
  188. package/dist/common/errors/reconnection-in-progress.js +0 -33
  189. package/dist/common/errors/reconnection-in-progress.js.map +0 -1
  190. package/dist/common/errors/reconnection.d.ts +0 -15
  191. package/dist/common/errors/stats.d.ts +0 -15
  192. package/dist/common/errors/webex-errors.d.ts +0 -93
  193. package/dist/common/errors/webex-meetings-error.d.ts +0 -20
  194. package/dist/common/events/events-scope.d.ts +0 -17
  195. package/dist/common/events/events.d.ts +0 -12
  196. package/dist/common/events/trigger-proxy.d.ts +0 -2
  197. package/dist/common/events/util.d.ts +0 -2
  198. package/dist/common/logs/logger-config.d.ts +0 -2
  199. package/dist/common/logs/logger-proxy.d.ts +0 -2
  200. package/dist/common/logs/request.d.ts +0 -36
  201. package/dist/common/queue.d.ts +0 -34
  202. package/dist/config.d.ts +0 -72
  203. package/dist/constants.d.ts +0 -1088
  204. package/dist/controls-options-manager/constants.d.ts +0 -4
  205. package/dist/controls-options-manager/enums.d.ts +0 -15
  206. package/dist/controls-options-manager/index.d.ts +0 -136
  207. package/dist/controls-options-manager/types.d.ts +0 -43
  208. package/dist/controls-options-manager/util.d.ts +0 -1
  209. package/dist/index.d.ts +0 -7
  210. package/dist/interceptors/index.d.ts +0 -2
  211. package/dist/interceptors/locusRetry.d.ts +0 -27
  212. package/dist/interpretation/collection.d.ts +0 -5
  213. package/dist/interpretation/index.d.ts +0 -5
  214. package/dist/interpretation/siLanguage.d.ts +0 -5
  215. package/dist/locus-info/controlsUtils.d.ts +0 -2
  216. package/dist/locus-info/embeddedAppsUtils.d.ts +0 -2
  217. package/dist/locus-info/fullState.d.ts +0 -2
  218. package/dist/locus-info/hostUtils.d.ts +0 -2
  219. package/dist/locus-info/index.d.ts +0 -322
  220. package/dist/locus-info/infoUtils.d.ts +0 -2
  221. package/dist/locus-info/mediaSharesUtils.d.ts +0 -2
  222. package/dist/locus-info/parser.d.ts +0 -272
  223. package/dist/locus-info/selfUtils.d.ts +0 -2
  224. package/dist/media/index.d.ts +0 -34
  225. package/dist/media/properties.d.ts +0 -93
  226. package/dist/media/util.d.ts +0 -2
  227. package/dist/mediaQualityMetrics/config.d.ts +0 -241
  228. package/dist/mediaQualityMetrics/config.js +0 -502
  229. package/dist/mediaQualityMetrics/config.js.map +0 -1
  230. package/dist/meeting/effectsState.js +0 -260
  231. package/dist/meeting/effectsState.js.map +0 -1
  232. package/dist/meeting/in-meeting-actions.d.ts +0 -167
  233. package/dist/meeting/index.d.ts +0 -1825
  234. package/dist/meeting/locusMediaRequest.d.ts +0 -74
  235. package/dist/meeting/muteState.d.ts +0 -178
  236. package/dist/meeting/request.d.ts +0 -295
  237. package/dist/meeting/request.type.d.ts +0 -11
  238. package/dist/meeting/state.d.ts +0 -9
  239. package/dist/meeting/util.d.ts +0 -119
  240. package/dist/meeting/voicea-meeting.d.ts +0 -16
  241. package/dist/meeting-info/collection.d.ts +0 -20
  242. package/dist/meeting-info/index.d.ts +0 -69
  243. package/dist/meeting-info/meeting-info-v2.d.ts +0 -123
  244. package/dist/meeting-info/request.d.ts +0 -22
  245. package/dist/meeting-info/util.d.ts +0 -2
  246. package/dist/meeting-info/utilv2.d.ts +0 -2
  247. package/dist/meetings/collection.d.ts +0 -40
  248. package/dist/meetings/index.d.ts +0 -390
  249. package/dist/meetings/meetings.types.d.ts +0 -4
  250. package/dist/meetings/request.d.ts +0 -27
  251. package/dist/meetings/util.d.ts +0 -18
  252. package/dist/member/index.d.ts +0 -160
  253. package/dist/member/member.types.js +0 -17
  254. package/dist/member/member.types.js.map +0 -1
  255. package/dist/member/types.d.ts +0 -32
  256. package/dist/member/util.d.ts +0 -2
  257. package/dist/members/collection.d.ts +0 -29
  258. package/dist/members/index.d.ts +0 -353
  259. package/dist/members/request.d.ts +0 -114
  260. package/dist/members/types.d.ts +0 -25
  261. package/dist/members/util.d.ts +0 -215
  262. package/dist/metrics/config.js +0 -276
  263. package/dist/metrics/config.js.map +0 -1
  264. package/dist/metrics/constants.d.ts +0 -70
  265. package/dist/metrics/index.d.ts +0 -45
  266. package/dist/multistream/mediaRequestManager.d.ts +0 -119
  267. package/dist/multistream/receiveSlot.d.ts +0 -68
  268. package/dist/multistream/receiveSlotManager.d.ts +0 -56
  269. package/dist/multistream/remoteMedia.d.ts +0 -72
  270. package/dist/multistream/remoteMediaGroup.d.ts +0 -49
  271. package/dist/multistream/remoteMediaManager.d.ts +0 -300
  272. package/dist/multistream/sendSlotManager.d.ts +0 -69
  273. package/dist/networkQualityMonitor/index.d.ts +0 -70
  274. package/dist/networkQualityMonitor/index.js +0 -221
  275. package/dist/networkQualityMonitor/index.js.map +0 -1
  276. package/dist/peer-connection-manager/index.js +0 -671
  277. package/dist/peer-connection-manager/index.js.map +0 -1
  278. package/dist/peer-connection-manager/util.js +0 -109
  279. package/dist/peer-connection-manager/util.js.map +0 -1
  280. package/dist/personal-meeting-room/index.d.ts +0 -47
  281. package/dist/personal-meeting-room/request.d.ts +0 -14
  282. package/dist/personal-meeting-room/util.d.ts +0 -2
  283. package/dist/reachability/clusterReachability.d.ts +0 -109
  284. package/dist/reachability/index.d.ts +0 -105
  285. package/dist/reachability/request.d.ts +0 -39
  286. package/dist/reachability/util.d.ts +0 -8
  287. package/dist/reactions/constants.d.ts +0 -3
  288. package/dist/reactions/reactions.d.ts +0 -4
  289. package/dist/reactions/reactions.type.d.ts +0 -52
  290. package/dist/reconnection-manager/index.d.ts +0 -136
  291. package/dist/recording-controller/enums.d.ts +0 -7
  292. package/dist/recording-controller/index.d.ts +0 -207
  293. package/dist/recording-controller/util.d.ts +0 -14
  294. package/dist/roap/collection.js +0 -62
  295. package/dist/roap/collection.js.map +0 -1
  296. package/dist/roap/handler.js +0 -275
  297. package/dist/roap/handler.js.map +0 -1
  298. package/dist/roap/index.d.ts +0 -86
  299. package/dist/roap/request.d.ts +0 -39
  300. package/dist/roap/state.js +0 -126
  301. package/dist/roap/state.js.map +0 -1
  302. package/dist/roap/turnDiscovery.d.ts +0 -155
  303. package/dist/roap/util.js +0 -75
  304. package/dist/roap/util.js.map +0 -1
  305. package/dist/rtcMetrics/constants.d.ts +0 -4
  306. package/dist/rtcMetrics/constants.js.map +0 -1
  307. package/dist/rtcMetrics/index.d.ts +0 -61
  308. package/dist/rtcMetrics/index.js +0 -197
  309. package/dist/rtcMetrics/index.js.map +0 -1
  310. package/dist/statsAnalyzer/global.d.ts +0 -36
  311. package/dist/statsAnalyzer/global.js +0 -126
  312. package/dist/statsAnalyzer/global.js.map +0 -1
  313. package/dist/statsAnalyzer/index.d.ts +0 -217
  314. package/dist/statsAnalyzer/index.js +0 -1013
  315. package/dist/statsAnalyzer/index.js.map +0 -1
  316. package/dist/statsAnalyzer/mqaUtil.d.ts +0 -48
  317. package/dist/statsAnalyzer/mqaUtil.js +0 -179
  318. package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
  319. package/dist/transcription/index.d.ts +0 -64
  320. package/dist/types/common/errors/reconnection-in-progress.d.ts +0 -9
  321. package/dist/types/mediaQualityMetrics/config.d.ts +0 -241
  322. package/dist/types/networkQualityMonitor/index.d.ts +0 -70
  323. package/dist/types/rtcMetrics/constants.d.ts +0 -4
  324. package/dist/types/rtcMetrics/index.d.ts +0 -71
  325. package/dist/types/statsAnalyzer/global.d.ts +0 -36
  326. package/dist/types/statsAnalyzer/index.d.ts +0 -217
  327. package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
  328. package/dist/webinar/collection.d.ts +0 -16
  329. package/dist/webinar/index.d.ts +0 -5
@@ -1,8 +1,11 @@
1
- enum RecordingAction {
1
+ export enum RecordingAction {
2
2
  Start = 'Start',
3
3
  Stop = 'Stop',
4
4
  Pause = 'Pause',
5
5
  Resume = 'Resume',
6
6
  }
7
7
 
8
- export default RecordingAction;
8
+ export enum RecordingType {
9
+ Premise = 'premise',
10
+ Cloud = 'cloud',
11
+ }
@@ -1,9 +1,9 @@
1
1
  import PermissionError from '../common/errors/permission';
2
+ import LoggerProxy from '../common/logs/logger-proxy';
2
3
  import {CONTROLS, HTTP_VERBS, SELF_POLICY} from '../constants';
3
4
  import MeetingRequest from '../meeting/request';
4
- import RecordingAction from './enums';
5
+ import {RecordingAction, RecordingType} from './enums';
5
6
  import Util from './util';
6
- import LoggerProxy from '../common/logs/logger-proxy';
7
7
 
8
8
  /**
9
9
  * @description Recording manages the recording functionality of the meeting object, there should only be one instantation of recording per meeting
@@ -228,11 +228,12 @@ export default class RecordingController {
228
228
 
229
229
  /**
230
230
  * @param {RecordingAction} action
231
+ * @param {RecordingType} recordingType
231
232
  * @private
232
233
  * @memberof RecordingController
233
234
  * @returns {Promise}
234
235
  */
235
- private recordingService(action: RecordingAction): Promise<any> {
236
+ private recordingService(action: RecordingAction, recordingType: RecordingType): Promise<any> {
236
237
  // @ts-ignore
237
238
  return this.request.request({
238
239
  body: {
@@ -242,6 +243,7 @@ export default class RecordingController {
242
243
  recording: {
243
244
  action: action.toLowerCase(),
244
245
  },
246
+ recordingType,
245
247
  },
246
248
  uri: `${this.serviceUrl}/loci/${this.locusId}/recording`,
247
249
  method: HTTP_VERBS.PUT,
@@ -276,14 +278,25 @@ export default class RecordingController {
276
278
  * @returns {Promise}
277
279
  */
278
280
  private recordingFacade(action: RecordingAction): Promise<any> {
281
+ const isPremiseRecordingEnabled = Util.isPremiseRecordingEnabled(
282
+ this.displayHints,
283
+ this.selfUserPolicies
284
+ );
279
285
  LoggerProxy.logger.log(
280
286
  `RecordingController:index#recordingFacade --> recording action [${action}]`
281
287
  );
282
288
 
289
+ let recordingType: RecordingType;
290
+ if (isPremiseRecordingEnabled) {
291
+ recordingType = RecordingType.Premise;
292
+ } else {
293
+ recordingType = RecordingType.Cloud;
294
+ }
295
+
283
296
  // assumes action is proper cased (i.e., Example)
284
297
  if (Util?.[`canUser${action}`](this.displayHints, this.selfUserPolicies)) {
285
298
  if (this.serviceUrl) {
286
- return this.recordingService(action);
299
+ return this.recordingService(action, recordingType);
287
300
  }
288
301
 
289
302
  return this.recordingControls(action);
@@ -1,33 +1,47 @@
1
1
  import {DISPLAY_HINTS, SELF_POLICY} from '../constants';
2
- import RecordingAction from './enums';
2
+ import {RecordingAction} from './enums';
3
3
  import MeetingUtil from '../meeting/util';
4
4
 
5
5
  const canUserStart = (
6
6
  displayHints: Array<string>,
7
7
  userPolicies: Record<SELF_POLICY, boolean>
8
8
  ): boolean =>
9
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_START) &&
9
+ (displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_START) ||
10
+ displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_START)) &&
10
11
  MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
11
12
 
12
13
  const canUserPause = (
13
14
  displayHints: Array<string>,
14
15
  userPolicies: Record<SELF_POLICY, boolean>
15
16
  ): boolean =>
16
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_PAUSE) &&
17
+ (displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_PAUSE) ||
18
+ displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_PAUSE)) &&
17
19
  MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
18
20
 
19
21
  const canUserResume = (
20
22
  displayHints: Array<string>,
21
23
  userPolicies: Record<SELF_POLICY, boolean>
22
24
  ): boolean =>
23
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_RESUME) &&
25
+ (displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_RESUME) ||
26
+ displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_RESUME)) &&
24
27
  MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
25
28
 
26
29
  const canUserStop = (
27
30
  displayHints: Array<string>,
28
31
  userPolicies: Record<SELF_POLICY, boolean>
29
32
  ): boolean =>
30
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_STOP) &&
33
+ (displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_STOP) ||
34
+ displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_STOP)) &&
35
+ MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
36
+
37
+ const isPremiseRecordingEnabled = (
38
+ displayHints: Array<string>,
39
+ userPolicies: Record<SELF_POLICY, boolean>
40
+ ): boolean =>
41
+ (displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_START) ||
42
+ displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_PAUSE) ||
43
+ displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_STOP) ||
44
+ displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_RESUME)) &&
31
45
  MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
32
46
 
33
47
  const extractLocusId = (url: string) => {
@@ -70,6 +84,7 @@ export default {
70
84
  canUserPause,
71
85
  canUserResume,
72
86
  canUserStop,
87
+ isPremiseRecordingEnabled,
73
88
  deriveRecordingStates,
74
89
  extractLocusId,
75
90
  };
package/src/roap/index.ts CHANGED
@@ -107,7 +107,7 @@ export default class Roap extends StatelessWebexPlugin {
107
107
  roapMessage,
108
108
  locusSelfUrl: meeting.selfUrl,
109
109
  mediaId: options.mediaId,
110
- meetingId: meeting.id,
110
+ isMultistream: meeting.isMultistream,
111
111
  locusMediaRequest: meeting.locusMediaRequest,
112
112
  })
113
113
  .then(() => {
@@ -141,7 +141,7 @@ export default class Roap extends StatelessWebexPlugin {
141
141
  roapMessage,
142
142
  locusSelfUrl: meeting.selfUrl,
143
143
  mediaId: options.mediaId,
144
- meetingId: meeting.id,
144
+ isMultistream: meeting.isMultistream,
145
145
  locusMediaRequest: meeting.locusMediaRequest,
146
146
  });
147
147
  }
@@ -170,7 +170,7 @@ export default class Roap extends StatelessWebexPlugin {
170
170
  roapMessage,
171
171
  locusSelfUrl: meeting.selfUrl,
172
172
  mediaId: options.mediaId,
173
- meetingId: meeting.id,
173
+ isMultistream: meeting.isMultistream,
174
174
  locusMediaRequest: meeting.locusMediaRequest,
175
175
  })
176
176
  .then(() => {
@@ -207,10 +207,9 @@ export default class Roap extends StatelessWebexPlugin {
207
207
  roapMessage,
208
208
  locusSelfUrl: meeting.selfUrl,
209
209
  mediaId: sendEmptyMediaId ? '' : meeting.mediaId,
210
- meetingId: meeting.id,
210
+ isMultistream: meeting.isMultistream,
211
211
  preferTranscoding: !meeting.isMultistream,
212
212
  locusMediaRequest: meeting.locusMediaRequest,
213
- ipVersion: MeetingUtil.getIpVersion(meeting.webex),
214
213
  })
215
214
  .then(({locus, mediaConnections}) => {
216
215
  if (mediaConnections) {
@@ -4,44 +4,13 @@ import {StatelessWebexPlugin} from '@webex/webex-core';
4
4
  import LoggerProxy from '../common/logs/logger-proxy';
5
5
  import {IP_VERSION, REACHABILITY} from '../constants';
6
6
  import {LocusMediaRequest} from '../meeting/locusMediaRequest';
7
+ import MeetingUtil from '../meeting/util';
8
+ import {ClientMediaPreferences} from '../reachability/reachability.types';
7
9
 
8
10
  /**
9
11
  * @class RoapRequest
10
12
  */
11
13
  export default class RoapRequest extends StatelessWebexPlugin {
12
- /**
13
- * Returns reachability data.
14
- * @param {Object} localSdp
15
- * @returns {Object}
16
- */
17
- async attachReachabilityData(localSdp) {
18
- let joinCookie;
19
-
20
- // @ts-ignore
21
- const reachabilityResult = await this.webex.meetings.reachability.getReachabilityResults();
22
-
23
- if (reachabilityResult && Object.keys(reachabilityResult).length) {
24
- localSdp.reachability = reachabilityResult;
25
- }
26
-
27
- // @ts-ignore
28
- const joinCookieRaw = await this.webex.boundedStorage
29
- .get(REACHABILITY.namespace, REACHABILITY.localStorageJoinCookie)
30
- .catch(() => {});
31
-
32
- if (joinCookieRaw) {
33
- try {
34
- joinCookie = JSON.parse(joinCookieRaw);
35
- } catch (e) {
36
- LoggerProxy.logger.error(
37
- `MeetingRequest#constructor --> Error in parsing join cookie data: ${e}`
38
- );
39
- }
40
- }
41
-
42
- return {localSdp, joinCookie};
43
- }
44
-
45
14
  /**
46
15
  * Sends a ROAP message
47
16
  * @param {Object} options
@@ -50,18 +19,16 @@ export default class RoapRequest extends StatelessWebexPlugin {
50
19
  * @param {String} options.mediaId
51
20
  * @param {String} options.correlationId
52
21
  * @param {String} options.meetingId
53
- * @param {IP_VERSION} options.ipVersion only required for offers
54
22
  * @returns {Promise} returns the response/failure of the request
55
23
  */
56
24
  async sendRoap(options: {
57
25
  roapMessage: any;
58
26
  locusSelfUrl: string;
59
27
  mediaId: string;
60
- meetingId: string;
61
- ipVersion?: IP_VERSION;
28
+ isMultistream: boolean;
62
29
  locusMediaRequest?: LocusMediaRequest;
63
30
  }) {
64
- const {roapMessage, locusSelfUrl, mediaId, locusMediaRequest, ipVersion} = options;
31
+ const {roapMessage, locusSelfUrl, isMultistream, mediaId, locusMediaRequest} = options;
65
32
 
66
33
  if (!mediaId) {
67
34
  LoggerProxy.logger.info('Roap:request#sendRoap --> sending empty mediaID');
@@ -74,23 +41,44 @@ export default class RoapRequest extends StatelessWebexPlugin {
74
41
 
75
42
  return Promise.reject(new Error('sendRoap called when locusMediaRequest is undefined'));
76
43
  }
77
- const {localSdp: localSdpWithReachabilityData, joinCookie} = await this.attachReachabilityData({
78
- roapMessage,
79
- });
44
+
45
+ let reachability;
46
+ let clientMediaPreferences: ClientMediaPreferences = {
47
+ // bare minimum fallback value that should allow us to join;
48
+ joinCookie: undefined,
49
+ ipver: IP_VERSION.unknown,
50
+ preferTranscoding: !isMultistream,
51
+ };
52
+
53
+ try {
54
+ clientMediaPreferences =
55
+ // @ts-ignore
56
+ await this.webex.meetings.reachability.getClientMediaPreferences(
57
+ isMultistream,
58
+ // @ts-ignore
59
+ MeetingUtil.getIpVersion(this.webex)
60
+ );
61
+ reachability =
62
+ // @ts-ignore
63
+ await this.webex.meetings.reachability.getReachabilityReportToAttachToRoap();
64
+ } catch (error) {
65
+ LoggerProxy.logger.error('Roap:request#sendRoap --> reachability error:', error);
66
+ }
80
67
 
81
68
  LoggerProxy.logger.info(
82
- `Roap:request#sendRoap --> ${locusSelfUrl} \n ${roapMessage.messageType} \n seq:${roapMessage.seq}`
69
+ `Roap:request#sendRoap --> ${roapMessage.messageType} seq:${roapMessage.seq} ${
70
+ clientMediaPreferences?.ipver ? `ipver=${clientMediaPreferences?.ipver} ` : ''
71
+ } ${locusSelfUrl}`
83
72
  );
84
73
 
85
74
  return locusMediaRequest
86
75
  .send({
87
76
  type: 'RoapMessage',
88
77
  selfUrl: locusSelfUrl,
89
- joinCookie,
90
78
  mediaId,
91
79
  roapMessage,
92
- reachability: localSdpWithReachabilityData.reachability,
93
- ipVersion,
80
+ reachability,
81
+ clientMediaPreferences,
94
82
  })
95
83
  .then((res) => {
96
84
  // always it will be the first mediaConnection Object
@@ -408,10 +408,8 @@ export default class TurnDiscovery {
408
408
  locusSelfUrl: meeting.selfUrl,
409
409
  // @ts-ignore - Fix missing type
410
410
  mediaId: isReconnecting ? '' : meeting.mediaId,
411
- meetingId: meeting.id,
411
+ isMultistream: meeting.isMultistream,
412
412
  locusMediaRequest: meeting.locusMediaRequest,
413
- // @ts-ignore - because of meeting.webex
414
- ipVersion: MeetingUtil.getIpVersion(meeting.webex),
415
413
  })
416
414
  .then(async (response) => {
417
415
  const {mediaConnections} = response;
@@ -451,7 +449,7 @@ export default class TurnDiscovery {
451
449
  locusSelfUrl: meeting.selfUrl,
452
450
  // @ts-ignore - fix type
453
451
  mediaId: meeting.mediaId,
454
- meetingId: meeting.id,
452
+ isMultistream: meeting.isMultistream,
455
453
  locusMediaRequest: meeting.locusMediaRequest,
456
454
  });
457
455
  }
@@ -2,9 +2,11 @@
2
2
  * Copyright (c) 2015-2023 Cisco Systems, Inc. See LICENSE file.
3
3
  */
4
4
  import {WebexPlugin} from '@webex/webex-core';
5
- import {MEETINGS} from '../constants';
5
+ import {get} from 'lodash';
6
+ import {HTTP_VERBS, MEETINGS, SELF_ROLES} from '../constants';
6
7
 
7
8
  import WebinarCollection from './collection';
9
+ import LoggerProxy from '../common/logs/logger-proxy';
8
10
 
9
11
  /**
10
12
  * @class Webinar
@@ -17,14 +19,16 @@ const Webinar = WebexPlugin.extend({
17
19
 
18
20
  props: {
19
21
  locusUrl: 'string', // appears current webinar's locus url
20
- webcastUrl: 'string', // current webinar's webcast url
21
- webinarAttendeesSearchingUrl: 'string', // current webinarAttendeesSearching url
22
+ webcastInstanceUrl: 'string', // current webinar's webcast instance url
22
23
  canManageWebcast: 'boolean', // appears the ability to manage webcast
24
+ selfIsPanelist: 'boolean', // self is panelist
25
+ selfIsAttendee: 'boolean', // self is attendee
26
+ practiceSessionEnabled: 'boolean', // practice session enabled
23
27
  },
24
28
 
25
29
  /**
26
30
  * Update the current locus url of the webinar
27
- * @param {string} locusUrl // locus url
31
+ * @param {string} locusUrl
28
32
  * @returns {void}
29
33
  */
30
34
  locusUrlUpdate(locusUrl) {
@@ -32,30 +36,72 @@ const Webinar = WebexPlugin.extend({
32
36
  },
33
37
 
34
38
  /**
35
- * Update the current webcast url of the meeting
36
- * @param {string} webcastUrl // webcast url
39
+ * Update the current webcast instance url of the meeting
40
+ * @param {object} payload
37
41
  * @returns {void}
38
42
  */
39
- webcastUrlUpdate(webcastUrl) {
40
- this.set('webcastUrl', webcastUrl);
43
+ updateWebcastUrl(payload) {
44
+ this.set('webcastInstanceUrl', get(payload, 'resources.webcastInstance.url'));
41
45
  },
42
46
 
43
47
  /**
44
- * Update the current webinarAttendeesSearching url of the meeting
45
- * @param {string} webinarAttendeesSearchingUrl // webinarAttendeesSearching url
48
+ * Update whether self has capability to manage start/stop webcast (only host can manage it)
49
+ * @param {boolean} canManageWebcast
46
50
  * @returns {void}
47
51
  */
48
- webinarAttendeesSearchingUrlUpdate(webinarAttendeesSearchingUrl) {
49
- this.set('webinarAttendeesSearchingUrl', webinarAttendeesSearchingUrl);
52
+ updateCanManageWebcast(canManageWebcast) {
53
+ this.set('canManageWebcast', canManageWebcast);
50
54
  },
51
55
 
52
56
  /**
53
- * Update whether self has capability to manage start/stop webcast (only host can manage it)
54
- * @param {boolean} canManageWebcast
57
+ * Updates user roles and manages associated state transitions
58
+ * @param {object} payload
59
+ * @param {string[]} payload.oldRoles - Previous roles of the user
60
+ * @param {string[]} payload.newRoles - New roles of the user
61
+ * @returns {{isPromoted: boolean, isDemoted: boolean}} Role transition states
62
+ */
63
+ updateRoleChanged(payload) {
64
+ const oldRoles = get(payload, 'oldRoles', []);
65
+ const newRoles = get(payload, 'newRoles', []);
66
+
67
+ const isPromoted =
68
+ oldRoles.includes(SELF_ROLES.ATTENDEE) && newRoles.includes(SELF_ROLES.PANELIST);
69
+ const isDemoted =
70
+ oldRoles.includes(SELF_ROLES.PANELIST) && newRoles.includes(SELF_ROLES.ATTENDEE);
71
+ this.set('selfIsPanelist', newRoles.includes(SELF_ROLES.PANELIST));
72
+ this.set('selfIsAttendee', newRoles.includes(SELF_ROLES.ATTENDEE));
73
+ this.updateCanManageWebcast(newRoles.includes(SELF_ROLES.MODERATOR));
74
+
75
+ return {isPromoted, isDemoted};
76
+ },
77
+
78
+ /**
79
+ * start or stop practice session for webinar
80
+ * @param {boolean} enabled
81
+ * @returns {Promise}
82
+ */
83
+ setPracticeSessionState(enabled) {
84
+ return this.request({
85
+ method: HTTP_VERBS.PATCH,
86
+ uri: `${this.locusUrl}/controls`,
87
+ body: {
88
+ practiceSession: {
89
+ enabled,
90
+ },
91
+ },
92
+ }).catch((error) => {
93
+ LoggerProxy.logger.error('Meeting:webinar#setPracticeSessionState failed', error);
94
+ throw error;
95
+ });
96
+ },
97
+
98
+ /**
99
+ * update practice session status
100
+ * @param {object} payload
55
101
  * @returns {void}
56
102
  */
57
- updateCanManageWebcast(canManageWebcast) {
58
- this.set('canManageWebcast', canManageWebcast);
103
+ updatePracticeSessionStatus(payload) {
104
+ this.set('practiceSessionEnabled', payload.enabled);
59
105
  },
60
106
  });
61
107
 
@@ -22,7 +22,7 @@ describe('plugin-meetings', () => {
22
22
 
23
23
  describe('Mute On Entry', () => {
24
24
  let manager;
25
-
25
+
26
26
  beforeEach(() => {
27
27
  request = {
28
28
  request: sinon.stub().returns(Promise.resolve()),
@@ -37,85 +37,85 @@ describe('plugin-meetings', () => {
37
37
  });
38
38
 
39
39
  describe('setMuteOnEntry', () => {
40
- it('rejects when correct display hint is not present enabled=false', () => {
40
+ it('rejects when correct display hint is not present enabled=false', () => {
41
41
  const result = manager.setMuteOnEntry(false);
42
-
42
+
43
43
  assert.notCalled(request.request);
44
-
44
+
45
45
  assert.isRejected(result);
46
46
  });
47
47
 
48
- it('rejects when correct display hint is not present enabled=true', () => {
48
+ it('rejects when correct display hint is not present enabled=true', () => {
49
49
  const result = manager.setMuteOnEntry(true);
50
-
50
+
51
51
  assert.notCalled(request.request);
52
-
52
+
53
53
  assert.isRejected(result);
54
54
  });
55
-
55
+
56
56
  it('can set mute on entry when the display hint is available enabled=true', () => {
57
57
  manager.setDisplayHints(['ENABLE_MUTE_ON_ENTRY']);
58
-
58
+
59
59
  const result = manager.setMuteOnEntry(true);
60
-
60
+
61
61
  assert.calledWith(request.request, { uri: 'test/id/controls',
62
62
  body: { muteOnEntry: { enabled: true } },
63
63
  method: HTTP_VERBS.PATCH});
64
-
64
+
65
65
  assert.deepEqual(result, request.request.firstCall.returnValue);
66
66
  });
67
67
 
68
68
  it('can set mute on entry when the display hint is available enabled=false', () => {
69
69
  manager.setDisplayHints(['DISABLE_MUTE_ON_ENTRY']);
70
-
70
+
71
71
  const result = manager.setMuteOnEntry(false);
72
-
72
+
73
73
  assert.calledWith(request.request, { uri: 'test/id/controls',
74
74
  body: { muteOnEntry: { enabled: false } },
75
75
  method: HTTP_VERBS.PATCH});
76
-
76
+
77
77
  assert.deepEqual(result, request.request.firstCall.returnValue);
78
78
  });
79
79
  });
80
80
 
81
81
  describe('setDisallowUnmute', () => {
82
- it('rejects when correct display hint is not present enabled=false', () => {
82
+ it('rejects when correct display hint is not present enabled=false', () => {
83
83
  const result = manager.setDisallowUnmute(false);
84
-
84
+
85
85
  assert.notCalled(request.request);
86
-
86
+
87
87
  assert.isRejected(result);
88
88
  });
89
89
 
90
- it('rejects when correct display hint is not present enabled=true', () => {
90
+ it('rejects when correct display hint is not present enabled=true', () => {
91
91
  const result = manager.setDisallowUnmute(true);
92
-
92
+
93
93
  assert.notCalled(request.request);
94
-
94
+
95
95
  assert.isRejected(result);
96
96
  });
97
-
98
- it('can set mute on entry when the display hint is available enabled=true', () => {
97
+
98
+ it('can set disallow unmute when ENABLE_HARD_MUTE display hint is available', () => {
99
99
  manager.setDisplayHints(['ENABLE_HARD_MUTE']);
100
-
100
+
101
101
  const result = manager.setDisallowUnmute(true);
102
-
102
+
103
103
  assert.calledWith(request.request, { uri: 'test/id/controls',
104
104
  body: { disallowUnmute: { enabled: true } },
105
105
  method: HTTP_VERBS.PATCH});
106
-
106
+
107
107
  assert.deepEqual(result, request.request.firstCall.returnValue);
108
108
  });
109
109
 
110
- it('can set mute on entry when the display hint is available enabled=false', () => {
110
+ it('can set allow unmute when DISABLE_HARD_MUTE display hint is available', () => {
111
111
  manager.setDisplayHints(['DISABLE_HARD_MUTE']);
112
-
112
+
113
113
  const result = manager.setDisallowUnmute(false);
114
-
114
+
115
115
  assert.calledWith(request.request, { uri: 'test/id/controls',
116
116
  body: { disallowUnmute: { enabled: false } },
117
117
  method: HTTP_VERBS.PATCH});
118
-
118
+
119
119
  assert.deepEqual(result, request.request.firstCall.returnValue);
120
120
  });
121
121
  });
@@ -218,7 +218,7 @@ describe('plugin-meetings', () => {
218
218
  })
219
219
  });
220
220
 
221
- it('rejects when correct display hint is not present mutedEnabled=false', () => {
221
+ it('rejects when correct display hint is not present mutedEnabled=false', () => {
222
222
  const result = manager.setMuteAll(false, false, false);
223
223
 
224
224
  assert.notCalled(request.request);
@@ -226,7 +226,7 @@ describe('plugin-meetings', () => {
226
226
  assert.isRejected(result);
227
227
  });
228
228
 
229
- it('rejects when correct display hint is not present mutedEnabled=true', () => {
229
+ it('rejects when correct display hint is not present mutedEnabled=true', () => {
230
230
  const result = manager.setMuteAll(true, false, false);
231
231
 
232
232
  assert.notCalled(request.request);
@@ -281,7 +281,31 @@ describe('plugin-meetings', () => {
281
281
 
282
282
  assert.deepEqual(result, request.request.firstCall.returnValue);
283
283
  });
284
+
285
+ it('can set mute all panelists when the display hint is available mutedEnabled=true', () => {
286
+ manager.setDisplayHints(['MUTE_ALL', 'DISABLE_HARD_MUTE', 'DISABLE_MUTE_ON_ENTRY']);
287
+
288
+ const result = manager.setMuteAll(true, true, true, ['panelist']);
289
+
290
+ assert.calledWith(request.request, { uri: 'test/id/controls',
291
+ body: { audio: { muted: true, disallowUnmute: true, muteOnEntry: true, roles: ['panelist'] } },
292
+ method: HTTP_VERBS.PATCH});
293
+
294
+ assert.deepEqual(result, request.request.firstCall.returnValue);
295
+ });
296
+
297
+ it('can set mute all attendees when the display hint is available mutedEnabled=true', () => {
298
+ manager.setDisplayHints(['MUTE_ALL', 'DISABLE_HARD_MUTE', 'DISABLE_MUTE_ON_ENTRY']);
299
+
300
+ const result = manager.setMuteAll(true, true, true, ['attendee']);
301
+
302
+ assert.calledWith(request.request, { uri: 'test/id/controls',
303
+ body: { audio: { muted: true, disallowUnmute: true, muteOnEntry: true, roles: ['attendee'] } },
304
+ method: HTTP_VERBS.PATCH});
305
+
306
+ assert.deepEqual(result, request.request.firstCall.returnValue);
307
+ });
284
308
  });
285
309
  });
286
310
  });
287
- });
311
+ });
@@ -348,6 +348,50 @@ describe('plugin-meetings', () => {
348
348
  });
349
349
  });
350
350
 
351
+ it('should call hasHints() with proper hints when `panelistEnabled` is true, attendeeCount is false', () => {
352
+ ControlsOptionsUtil.canUpdateViewTheParticipantsList({properties: {enabled: true, panelistEnabled: true, attendeeCount: false}}, []);
353
+
354
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
355
+ requiredHints: [DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST,
356
+ DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST,
357
+ DISPLAY_HINTS.DISABLE_SHOW_ATTENDEE_COUNT],
358
+ displayHints: [],
359
+ });
360
+ });
361
+
362
+ it('should call hasHints() with proper hints when `panelistEnabled` is true, attendeeCount is true', () => {
363
+ ControlsOptionsUtil.canUpdateViewTheParticipantsList({properties: {enabled: true, panelistEnabled: true, attendeeCount: true}}, []);
364
+
365
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
366
+ requiredHints: [DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST,
367
+ DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST,
368
+ DISPLAY_HINTS.ENABLE_SHOW_ATTENDEE_COUNT],
369
+ displayHints: [],
370
+ });
371
+ });
372
+
373
+ it('should call hasHints() with proper hints when `panelistEnabled` is false, attendeeCount is false', () => {
374
+ ControlsOptionsUtil.canUpdateViewTheParticipantsList({properties: {enabled: true, panelistEnabled: false, attendeeCount: false}}, []);
375
+
376
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
377
+ requiredHints: [DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST,
378
+ DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST,
379
+ DISPLAY_HINTS.DISABLE_SHOW_ATTENDEE_COUNT],
380
+ displayHints: [],
381
+ });
382
+ });
383
+
384
+ it('should call hasHints() with proper hints when `panelistEnabled` is false, attendeeCount is true', () => {
385
+ ControlsOptionsUtil.canUpdateViewTheParticipantsList({properties: {enabled: true, panelistEnabled: false, attendeeCount: true}}, []);
386
+
387
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
388
+ requiredHints: [DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST,
389
+ DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST,
390
+ DISPLAY_HINTS.ENABLE_SHOW_ATTENDEE_COUNT],
391
+ displayHints: [],
392
+ });
393
+ });
394
+
351
395
  it('should return the resolution of hasHints()', () => {
352
396
  const expected = 'example-return-value';
353
397
  ControlsOptionsUtil.hasHints.returns(expected);