@webex/plugin-meetings 2.38.2 → 2.39.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/constants.js +5 -1
  2. package/dist/constants.js.map +1 -1
  3. package/dist/controls-options-manager/constants.js +14 -0
  4. package/dist/controls-options-manager/constants.js.map +1 -0
  5. package/dist/controls-options-manager/enums.js +15 -0
  6. package/dist/controls-options-manager/enums.js.map +1 -0
  7. package/dist/controls-options-manager/index.js +203 -0
  8. package/dist/controls-options-manager/index.js.map +1 -0
  9. package/dist/controls-options-manager/util.js +28 -0
  10. package/dist/controls-options-manager/util.js.map +1 -0
  11. package/dist/meeting/in-meeting-actions.js +8 -0
  12. package/dist/meeting/in-meeting-actions.js.map +1 -1
  13. package/dist/meeting/index.js +54 -7
  14. package/dist/meeting/index.js.map +1 -1
  15. package/dist/metrics/config.js +1 -11
  16. package/dist/metrics/config.js.map +1 -1
  17. package/dist/metrics/index.js +3 -25
  18. package/dist/metrics/index.js.map +1 -1
  19. package/package.json +17 -17
  20. package/src/constants.ts +4 -0
  21. package/src/controls-options-manager/constants.ts +5 -0
  22. package/src/controls-options-manager/enums.ts +6 -0
  23. package/src/controls-options-manager/index.ts +183 -0
  24. package/src/controls-options-manager/util.ts +20 -0
  25. package/src/meeting/in-meeting-actions.ts +16 -0
  26. package/src/meeting/index.ts +49 -0
  27. package/src/metrics/config.ts +0 -10
  28. package/src/metrics/index.ts +3 -24
  29. package/test/unit/spec/controls-options-manager/index.js +124 -0
  30. package/test/unit/spec/controls-options-manager/util.js +66 -0
  31. package/test/unit/spec/meeting/in-meeting-actions.ts +8 -0
  32. package/test/unit/spec/meeting/index.js +15 -0
@@ -0,0 +1,183 @@
1
+ import {camelCase} from 'lodash';
2
+ import PermissionError from '../common/errors/permission';
3
+ import {CONTROLS, HTTP_VERBS} from '../constants';
4
+ import MeetingRequest from '../meeting/request';
5
+ import LoggerProxy from '../common/logs/logger-proxy';
6
+ import Setting from './enums';
7
+ import Util from './util';
8
+ import {CAN_SET, CAN_UNSET, ENABLED} from './constants';
9
+
10
+ /**
11
+ * docs
12
+ * https://sqbu-github.cisco.com/pages/WebExSquared/locus/guides/mute.html
13
+ * https://confluence-eng-gpk2.cisco.com/conf/display/LOCUS/Hard+Mute+and+Audio+Privacy#HardMuteandAudioPrivacy-SelfMuteonEntry
14
+ * https://confluence-eng-gpk2.cisco.com/conf/pages/viewpage.action?spaceKey=UC&title=WEBEX-124454%3A+UCF%3A+Hard+mute+support+for+Teams+joining+Webex+meeting
15
+ * https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-180867
16
+ * https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-393351
17
+ */
18
+
19
+ /**
20
+ * @description ControlsOptionsManager is responsible for handling the behavior of participant controls when somebody joins a meeting
21
+ * @export
22
+ * @private
23
+ * @class Recording
24
+ */
25
+ export default class ControlsOptionsManager {
26
+ /**
27
+ * @instance
28
+ * @type {MeetingRequest}
29
+ * @private
30
+ * @memberof ControlsOptionsManager
31
+ */
32
+ private request: MeetingRequest;
33
+
34
+ /**
35
+ * @instance
36
+ * @type {Array}
37
+ * @private
38
+ * @memberof ControlsOptionsManager
39
+ */
40
+ private displayHints: Array<string> = [];
41
+
42
+ /**
43
+ * @instance
44
+ * @type {string}
45
+ * @private
46
+ * @memberof ControlsOptionsManager
47
+ */
48
+ private locusUrl: string;
49
+
50
+ /**
51
+ * @param {MeetingRequest} request
52
+ * @param {Object} options
53
+ * @constructor
54
+ * @memberof ControlsOptionsManager
55
+ */
56
+ constructor(
57
+ request: MeetingRequest,
58
+ options?: {
59
+ locusUrl: string;
60
+ displayHints?: Array<string>;
61
+ }
62
+ ) {
63
+ this.initialize(request);
64
+ this.set(options);
65
+ }
66
+
67
+ /**
68
+ * @param {MeetingRequest} request
69
+ * @returns {void}
70
+ * @private
71
+ * @memberof ControlsOptionsManager
72
+ */
73
+ private initialize(request: MeetingRequest) {
74
+ this.request = request;
75
+ }
76
+
77
+ /**
78
+ * @param {Object} options
79
+ * @returns {void}
80
+ * @public
81
+ * @memberof ControlsOptionsManager
82
+ */
83
+ public set(options?: {locusUrl: string; displayHints?: Array<string>}) {
84
+ this.extract(options);
85
+ }
86
+
87
+ /**
88
+ * @param {string} url
89
+ * @returns {void}
90
+ * @public
91
+ * @memberof ControlsOptionsManager
92
+ */
93
+ public setLocusUrl(url: string) {
94
+ this.locusUrl = url;
95
+ }
96
+
97
+ /**
98
+ * @param {Array} hints
99
+ * @returns {void}
100
+ * @public
101
+ * @memberof ControlsOptionsManager
102
+ */
103
+ public setDisplayHints(hints: Array<string>) {
104
+ this.displayHints = hints;
105
+ }
106
+
107
+ /**
108
+ * @returns {string}
109
+ * @public
110
+ * @memberof ControlsOptionsManager
111
+ */
112
+ public getLocusUrl() {
113
+ return this.locusUrl;
114
+ }
115
+
116
+ /**
117
+ * @returns {Array}
118
+ * @public
119
+ * @memberof ControlsOptionsManager
120
+ */
121
+ public getDisplayHints() {
122
+ return this.displayHints;
123
+ }
124
+
125
+ /**
126
+ * @param {Object} options
127
+ * @returns {void}
128
+ * @private
129
+ * @memberof ControlsOptionsManager
130
+ */
131
+ private extract(options?: {locusUrl: string; displayHints?: Array<string>}) {
132
+ this.setDisplayHints(options?.displayHints);
133
+ this.setLocusUrl(options?.locusUrl);
134
+ }
135
+
136
+ /**
137
+ * @param {Setting} setting
138
+ * @param {boolean} enabled
139
+ * @private
140
+ * @memberof ControlsOptionsManager
141
+ * @returns {Promise}
142
+ */
143
+ private setControls(setting: Setting, enabled: boolean): Promise<any> {
144
+ LoggerProxy.logger.log(`ControlsOptionsManager:index#setControls --> ${setting} [${enabled}]`);
145
+
146
+ if (Util?.[`${enabled ? CAN_SET : CAN_UNSET}${setting}`](this.displayHints)) {
147
+ // @ts-ignore
148
+ return this.request.request({
149
+ uri: `${this.locusUrl}/${CONTROLS}`,
150
+ body: {
151
+ [camelCase(setting)]: {
152
+ [ENABLED]: enabled,
153
+ },
154
+ },
155
+ method: HTTP_VERBS.PATCH,
156
+ });
157
+ }
158
+
159
+ return Promise.reject(
160
+ new PermissionError(`${setting} [${enabled}] not allowed, due to moderator property.`)
161
+ );
162
+ }
163
+
164
+ /**
165
+ * @public
166
+ * @param {boolean} enabled
167
+ * @memberof ControlsOptionsManager
168
+ * @returns {Promise}
169
+ */
170
+ public setMuteOnEntry(enabled: boolean): Promise<any> {
171
+ return this.setControls(Setting.muteOnEntry, enabled);
172
+ }
173
+
174
+ /**
175
+ * @public
176
+ * @param {boolean} enabled
177
+ * @memberof ControlsOptionsManager
178
+ * @returns {Promise}
179
+ */
180
+ public setDisallowUnmute(enabled: boolean): Promise<any> {
181
+ return this.setControls(Setting.disallowUnmute, enabled);
182
+ }
183
+ }
@@ -0,0 +1,20 @@
1
+ import {DISPLAY_HINTS} from '../constants';
2
+
3
+ const canSetMuteOnEntry = (displayHints: Array<string>): boolean =>
4
+ displayHints.includes(DISPLAY_HINTS.ENABLE_MUTE_ON_ENTRY);
5
+
6
+ const canSetDisallowUnmute = (displayHints: Array<string>): boolean =>
7
+ displayHints.includes(DISPLAY_HINTS.ENABLE_HARD_MUTE);
8
+
9
+ const canUnsetMuteOnEntry = (displayHints: Array<string>): boolean =>
10
+ displayHints.includes(DISPLAY_HINTS.DISABLE_MUTE_ON_ENTRY);
11
+
12
+ const canUnsetDisallowUnmute = (displayHints: Array<string>): boolean =>
13
+ displayHints.includes(DISPLAY_HINTS.DISABLE_HARD_MUTE);
14
+
15
+ export default {
16
+ canSetMuteOnEntry,
17
+ canSetDisallowUnmute,
18
+ canUnsetMuteOnEntry,
19
+ canUnsetDisallowUnmute,
20
+ };
@@ -13,6 +13,10 @@ interface IInMeetingActions {
13
13
  canAdmitParticipant?: boolean;
14
14
  canLock?: boolean;
15
15
  canUnlock?: boolean;
16
+ canSetMuteOnEntry?: boolean;
17
+ canUnsetMuteOnEntry?: boolean;
18
+ canSetDisallowUnmute?: boolean;
19
+ canUnsetDisallowUnmute?: boolean;
16
20
  canAssignHost?: boolean;
17
21
  canStartRecording?: boolean;
18
22
  canPauseRecording?: boolean;
@@ -57,6 +61,14 @@ export default class InMeetingActions implements IInMeetingActions {
57
61
 
58
62
  canStopRecording = null;
59
63
 
64
+ canSetMuteOnEntry = null;
65
+
66
+ canUnsetMuteOnEntry = null;
67
+
68
+ canSetDisallowUnmute = null;
69
+
70
+ canUnsetDisallowUnmute = null;
71
+
60
72
  canRaiseHand = null;
61
73
 
62
74
  canLowerAllHands = null;
@@ -93,6 +105,10 @@ export default class InMeetingActions implements IInMeetingActions {
93
105
  canLock: this.canLock,
94
106
  canUnlock: this.canUnlock,
95
107
  canAssignHost: this.canAssignHost,
108
+ canSetMuteOnEntry: this.canSetMuteOnEntry,
109
+ canUnsetMuteOnEntry: this.canUnsetMuteOnEntry,
110
+ canSetDisallowUnmute: this.canSetDisallowUnmute,
111
+ canUnsetDisallowUnmute: this.canUnsetDisallowUnmute,
96
112
  canStartRecording: this.canStartRecording,
97
113
  canPauseRecording: this.canPauseRecording,
98
114
  canResumeRecording: this.canResumeRecording,
@@ -31,6 +31,7 @@ import MeetingRequest from './request';
31
31
  import Members from '../members/index';
32
32
  import MeetingUtil from './util';
33
33
  import RecordingUtil from '../recording-controller/util';
34
+ import ControlsOptionsUtil from '../controls-options-manager/util';
34
35
  import MediaUtil from '../media/util';
35
36
  import Transcription from '../transcription';
36
37
  import PasswordError from '../common/errors/password-error';
@@ -90,6 +91,7 @@ import {Reaction, ReactionType, SkinToneType} from '../reactions/reactions.type'
90
91
 
91
92
  import InMeetingActions from './in-meeting-actions';
92
93
  import RecordingController from '../recording-controller';
94
+ import ControlsOptionsManager from '../controls-options-manager';
93
95
 
94
96
  const {isBrowser} = BrowserDetection();
95
97
 
@@ -455,6 +457,7 @@ export default class Meeting extends StatelessWebexPlugin {
455
457
  queuedMediaUpdates: any[];
456
458
  recording: any;
457
459
  recordingController: RecordingController;
460
+ controlsOptionsManager: ControlsOptionsManager;
458
461
  requiredCaptcha: any;
459
462
  shareStatus: string;
460
463
  statsAnalyzer: StatsAnalyzer;
@@ -1002,6 +1005,18 @@ export default class Meeting extends StatelessWebexPlugin {
1002
1005
  displayHints: [],
1003
1006
  });
1004
1007
 
1008
+ /**
1009
+ * The class that helps to control recording functions: start, stop, pause, resume, etc
1010
+ * @instance
1011
+ * @type {ControlsOptionsManager}
1012
+ * @public
1013
+ * @memberof Meeting
1014
+ */
1015
+ this.controlsOptionsManager = new ControlsOptionsManager(this.meetingRequest, {
1016
+ locusUrl: this.locusInfo?.url,
1017
+ displayHints: [],
1018
+ });
1019
+
1005
1020
  this.setUpLocusInfoListeners();
1006
1021
  this.locusInfo.init(attrs.locus ? attrs.locus : {});
1007
1022
  this.hasJoinedOnce = false;
@@ -2020,6 +2035,7 @@ export default class Meeting extends StatelessWebexPlugin {
2020
2035
  this.locusUrl = payload;
2021
2036
  this.locusId = this.locusUrl?.split('/').pop();
2022
2037
  this.recordingController.setLocusUrl(this.locusUrl);
2038
+ this.controlsOptionsManager.setLocusUrl(this.locusUrl);
2023
2039
  });
2024
2040
  }
2025
2041
 
@@ -2085,6 +2101,16 @@ export default class Meeting extends StatelessWebexPlugin {
2085
2101
  canAdmitParticipant: MeetingUtil.canAdmitParticipant(payload.info.userDisplayHints),
2086
2102
  canLock: MeetingUtil.canUserLock(payload.info.userDisplayHints),
2087
2103
  canUnlock: MeetingUtil.canUserUnlock(payload.info.userDisplayHints),
2104
+ canSetDisallowUnmute: ControlsOptionsUtil.canSetDisallowUnmute(
2105
+ payload.info.userDisplayHints
2106
+ ),
2107
+ canUnsetDisallowUnmute: ControlsOptionsUtil.canUnsetDisallowUnmute(
2108
+ payload.info.userDisplayHints
2109
+ ),
2110
+ canSetMuteOnEntry: ControlsOptionsUtil.canSetMuteOnEntry(payload.info.userDisplayHints),
2111
+ canUnsetMuteOnEntry: ControlsOptionsUtil.canUnsetMuteOnEntry(
2112
+ payload.info.userDisplayHints
2113
+ ),
2088
2114
  canStartRecording: RecordingUtil.canUserStart(payload.info.userDisplayHints),
2089
2115
  canStopRecording: RecordingUtil.canUserStop(payload.info.userDisplayHints),
2090
2116
  canPauseRecording: RecordingUtil.canUserPause(payload.info.userDisplayHints),
@@ -2113,6 +2139,7 @@ export default class Meeting extends StatelessWebexPlugin {
2113
2139
  });
2114
2140
 
2115
2141
  this.recordingController.setDisplayHints(payload.info.userDisplayHints);
2142
+ this.controlsOptionsManager.setDisplayHints(payload.info.userDisplayHints);
2116
2143
 
2117
2144
  if (changed) {
2118
2145
  Trigger.trigger(
@@ -5526,6 +5553,28 @@ export default class Meeting extends StatelessWebexPlugin {
5526
5553
  return this.recordingController.startRecording();
5527
5554
  }
5528
5555
 
5556
+ /**
5557
+ * set the mute on entry flag for participants if you're the host
5558
+ * @returns {Promise}
5559
+ * @param {boolean} enabled
5560
+ * @public
5561
+ * @memberof Meeting
5562
+ */
5563
+ public setMuteOnEntry(enabled: boolean) {
5564
+ return this.controlsOptionsManager.setMuteOnEntry(enabled);
5565
+ }
5566
+
5567
+ /**
5568
+ * set the disallow unmute flag for participants if you're the host
5569
+ * @returns {Promise}
5570
+ * @param {boolean} enabled
5571
+ * @public
5572
+ * @memberof Meeting
5573
+ */
5574
+ public setDisallowUnmute(enabled: boolean) {
5575
+ return this.controlsOptionsManager.setDisallowUnmute(enabled);
5576
+ }
5577
+
5529
5578
  /**
5530
5579
  * End the recording of this meeting
5531
5580
  * @returns {Promise}
@@ -481,15 +481,5 @@ export const errorObjects = {
481
481
 
482
482
  export const UNKNOWN = 'unknown';
483
483
 
484
- export const OS_NAME = {
485
- WINDOWS: 'windows',
486
- MAC: 'mac',
487
- IOS: 'ios',
488
- ANDROID: 'android',
489
- CHROME: 'chrome',
490
- LINUX: 'linux',
491
- OTHERS: 'other',
492
- };
493
-
494
484
  export const CLIENT_NAME = 'webex-js-sdk';
495
485
  export const PLATFORM = 'Web';
@@ -8,6 +8,7 @@ import uuid from 'uuid';
8
8
  import window from 'global/window';
9
9
  import anonymize from 'ip-anonymize';
10
10
 
11
+ import {getOSNameInternal} from '@webex/internal-plugin-metrics';
11
12
  import LoggerProxy from '../common/logs/logger-proxy';
12
13
  import {MEETING_ERRORS} from '../constants';
13
14
  import BrowserDetection from '../common/browser-detection';
@@ -16,22 +17,11 @@ import {
16
17
  error,
17
18
  eventType,
18
19
  errorCodes as ERROR_CODE,
19
- OS_NAME,
20
20
  UNKNOWN,
21
21
  CLIENT_NAME,
22
22
  mediaType,
23
23
  } from './config';
24
24
 
25
- const OSMap = {
26
- // @ts-ignore
27
- 'Chrome OS': OS_NAME.chrome,
28
- macOS: OS_NAME.MAC,
29
- Windows: OS_NAME.WINDOWS,
30
- iOS: OS_NAME.IOS,
31
- Android: OS_NAME.ANDROID,
32
- Linux: OS_NAME.LINUX,
33
- };
34
-
35
25
  const {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
36
26
 
37
27
  // Apply a CIDR /28 format to the IPV4 and /96 to the IPV6 addresses
@@ -205,7 +195,7 @@ class Metrics {
205
195
  localNetworkPrefix: anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress),
206
196
  osVersion: getOSVersion() || 'unknown',
207
197
  subClientType: options.subClientType,
208
- os: this.getOsName(),
198
+ os: getOSNameInternal(),
209
199
  browser: getBrowserName(),
210
200
  browserVersion: getBrowserVersion(),
211
201
  },
@@ -256,17 +246,6 @@ class Metrics {
256
246
  return payload;
257
247
  }
258
248
 
259
- /**
260
- * returns metrics friendly OS versions
261
- * @param {String} osName Os name
262
- * @returns {String}
263
- * @private
264
- * @memberof Metrics
265
- */
266
- private getOsName() {
267
- return OSMap[getOSName()] ?? OS_NAME.OTHERS;
268
- }
269
-
270
249
  /**
271
250
  * get the payload specific for a media quality event through call analyzer
272
251
  * @param {String} eventType the event name
@@ -311,7 +290,7 @@ class Metrics {
311
290
  clientType: options.clientType, // TODO: Only clientType: 'TEAMS_CLIENT' is whitelisted
312
291
  clientVersion: `${CLIENT_NAME}/${this.webex.version}`,
313
292
  localNetworkPrefix: anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress),
314
- os: this.getOsName(),
293
+ os: getOSNameInternal(),
315
294
  osVersion: getOSVersion() || UNKNOWN,
316
295
  subClientType: options.subClientType,
317
296
  browser: getBrowserName(),
@@ -0,0 +1,124 @@
1
+ import ControlsOptionsManager from '@webex/plugin-meetings/src/controls-options-manager';
2
+ import sinon from 'sinon';
3
+ import {assert} from '@webex/test-helper-chai';
4
+ import { HTTP_VERBS } from '@webex/plugin-meetings/src/constants';
5
+
6
+ describe('plugin-meetings', () => {
7
+ describe('controls-options-manager tests', () => {
8
+ describe('index', () => {
9
+ let request;
10
+
11
+ describe('class tests', () => {
12
+ it('can set and extract new values later on', () => {
13
+ const manager = new ControlsOptionsManager({});
14
+ assert.isUndefined(manager.getLocusUrl());
15
+ manager.set({
16
+ locusUrl: 'test/id',
17
+ })
18
+ assert(manager.getLocusUrl(), 'test/id');
19
+ });
20
+ });
21
+
22
+ describe('Mute On Entry', () => {
23
+ let manager;
24
+
25
+ beforeEach(() => {
26
+ request = {
27
+ request: sinon.stub().returns(Promise.resolve()),
28
+ };
29
+
30
+ manager = new ControlsOptionsManager(request);
31
+
32
+ manager.set({
33
+ locusUrl: 'test/id',
34
+ displayHints: [],
35
+ })
36
+ });
37
+
38
+ describe('setMuteOnEntry', () => {
39
+ it('rejects when correct display hint is not present enabled=false', () => {
40
+ const result = manager.setMuteOnEntry(false);
41
+
42
+ assert.notCalled(request.request);
43
+
44
+ assert.isRejected(result);
45
+ });
46
+
47
+ it('rejects when correct display hint is not present enabled=true', () => {
48
+ const result = manager.setMuteOnEntry(true);
49
+
50
+ assert.notCalled(request.request);
51
+
52
+ assert.isRejected(result);
53
+ });
54
+
55
+ it('can set mute on entry when the display hint is available enabled=true', () => {
56
+ manager.setDisplayHints(['ENABLE_MUTE_ON_ENTRY']);
57
+
58
+ const result = manager.setMuteOnEntry(true);
59
+
60
+ assert.calledWith(request.request, { uri: 'test/id/controls',
61
+ body: { muteOnEntry: { enabled: true } },
62
+ method: HTTP_VERBS.PATCH});
63
+
64
+ assert.deepEqual(result, request.request.firstCall.returnValue);
65
+ });
66
+
67
+ it('can set mute on entry when the display hint is available enabled=false', () => {
68
+ manager.setDisplayHints(['DISABLE_MUTE_ON_ENTRY']);
69
+
70
+ const result = manager.setMuteOnEntry(false);
71
+
72
+ assert.calledWith(request.request, { uri: 'test/id/controls',
73
+ body: { muteOnEntry: { enabled: false } },
74
+ method: HTTP_VERBS.PATCH});
75
+
76
+ assert.deepEqual(result, request.request.firstCall.returnValue);
77
+ });
78
+ });
79
+
80
+ describe('setDisallowUnmute', () => {
81
+ it('rejects when correct display hint is not present enabled=false', () => {
82
+ const result = manager.setDisallowUnmute(false);
83
+
84
+ assert.notCalled(request.request);
85
+
86
+ assert.isRejected(result);
87
+ });
88
+
89
+ it('rejects when correct display hint is not present enabled=true', () => {
90
+ const result = manager.setDisallowUnmute(true);
91
+
92
+ assert.notCalled(request.request);
93
+
94
+ assert.isRejected(result);
95
+ });
96
+
97
+ it('can set mute on entry when the display hint is available enabled=true', () => {
98
+ manager.setDisplayHints(['ENABLE_HARD_MUTE']);
99
+
100
+ const result = manager.setDisallowUnmute(true);
101
+
102
+ assert.calledWith(request.request, { uri: 'test/id/controls',
103
+ body: { disallowUnmute: { enabled: true } },
104
+ method: HTTP_VERBS.PATCH});
105
+
106
+ assert.deepEqual(result, request.request.firstCall.returnValue);
107
+ });
108
+
109
+ it('can set mute on entry when the display hint is available enabled=false', () => {
110
+ manager.setDisplayHints(['DISABLE_HARD_MUTE']);
111
+
112
+ const result = manager.setDisallowUnmute(false);
113
+
114
+ assert.calledWith(request.request, { uri: 'test/id/controls',
115
+ body: { disallowUnmute: { enabled: false } },
116
+ method: HTTP_VERBS.PATCH});
117
+
118
+ assert.deepEqual(result, request.request.firstCall.returnValue);
119
+ });
120
+ });
121
+ });
122
+ });
123
+ });
124
+ });
@@ -0,0 +1,66 @@
1
+ import ControlsOptionsUtil from '@webex/plugin-meetings/src/controls-options-manager/util';
2
+ import { assert } from 'chai';
3
+
4
+ describe('plugin-meetings', () => {
5
+ describe('controls-option-manager tests', () => {
6
+ describe('util tests', () => {
7
+
8
+ let locusInfo;
9
+
10
+ beforeEach(() => {
11
+ locusInfo = {
12
+ parsedLocus: {
13
+ info: {
14
+ userDisplayHints: [],
15
+ },
16
+ },
17
+ };
18
+ });
19
+
20
+ describe('canUserSetMuteOnEntry', () => {
21
+ it('can set mute on entry enable', () => {
22
+ locusInfo.parsedLocus.info.userDisplayHints.push('ENABLE_MUTE_ON_ENTRY');
23
+
24
+ assert.equal(ControlsOptionsUtil.canSetMuteOnEntry(locusInfo.parsedLocus.info.userDisplayHints), true);
25
+ });
26
+
27
+ it('can set mute on entry disable', () => {
28
+ locusInfo.parsedLocus.info.userDisplayHints.push('DISABLE_MUTE_ON_ENTRY');
29
+
30
+ assert.equal(ControlsOptionsUtil.canUnsetMuteOnEntry(locusInfo.parsedLocus.info.userDisplayHints), true);
31
+ });
32
+
33
+ it('rejects when correct display hint is not present for setting mute on entry', () => {
34
+ assert.equal(ControlsOptionsUtil.canSetMuteOnEntry(locusInfo.parsedLocus.info.userDisplayHints), false);
35
+ });
36
+
37
+ it('rejects when correct display hint is not present for unsetting mute on entry', () => {
38
+ assert.equal(ControlsOptionsUtil.canUnsetMuteOnEntry(locusInfo.parsedLocus.info.userDisplayHints), false);
39
+ });
40
+ });
41
+
42
+ describe('canSetDisallowUnmute', () => {
43
+ it('can set disallow unmute enable', () => {
44
+ locusInfo.parsedLocus.info.userDisplayHints.push('ENABLE_HARD_MUTE');
45
+
46
+ assert.equal(ControlsOptionsUtil.canSetDisallowUnmute(locusInfo.parsedLocus.info.userDisplayHints), true);
47
+ });
48
+
49
+ it('can set disallow unmute disable', () => {
50
+ locusInfo.parsedLocus.info.userDisplayHints.push('DISABLE_HARD_MUTE');
51
+
52
+ assert.equal(ControlsOptionsUtil.canUnsetDisallowUnmute(locusInfo.parsedLocus.info.userDisplayHints), true);
53
+ });
54
+
55
+ it('rejects when correct display hint is not present', () => {
56
+ assert.equal(ControlsOptionsUtil.canSetDisallowUnmute(locusInfo.parsedLocus.info.userDisplayHints), false);
57
+ });
58
+
59
+ it('rejects when correct display hint is not present', () => {
60
+ assert.equal(ControlsOptionsUtil.canUnsetDisallowUnmute(locusInfo.parsedLocus.info.userDisplayHints), false);
61
+ });
62
+ });
63
+
64
+ });
65
+ });
66
+ });
@@ -13,6 +13,10 @@ describe('plugin-meetings', () => {
13
13
  canStartRecording: null,
14
14
  canPauseRecording: null,
15
15
  canResumeRecording: null,
16
+ canSetMuteOnEntry: null,
17
+ canUnsetMuteOnEntry: null,
18
+ canSetDisallowUnmute: null,
19
+ canUnsetDisallowUnmute: null,
16
20
  canStopRecording: null,
17
21
  canRaiseHand: null,
18
22
  canLowerAllHands: null,
@@ -49,6 +53,10 @@ describe('plugin-meetings', () => {
49
53
  'canPauseRecording',
50
54
  'canResumeRecording',
51
55
  'canStopRecording',
56
+ 'canSetMuteOnEntry',
57
+ 'canUnsetMuteOnEntry',
58
+ 'canSetDisallowUnmute',
59
+ 'canUnsetDisallowUnmute',
52
60
  'canRaiseHand',
53
61
  'canLowerAllHands',
54
62
  'canLowerSomeoneElsesHand',