@webex/plugin-meetings 3.0.0-beta.80 → 3.0.0-beta.81

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.
@@ -1,9 +1,103 @@
1
- declare const _default: {
2
- canSetMuteOnEntry: (displayHints: string[]) => boolean;
3
- canSetDisallowUnmute: (displayHints: string[]) => boolean;
4
- canSetMuted: (displayHints: string[]) => boolean;
5
- canUnsetMuteOnEntry: (displayHints: string[]) => boolean;
6
- canUnsetDisallowUnmute: (displayHints: string[]) => boolean;
7
- canUnsetMuted: (displayHints: string[]) => boolean;
8
- };
9
- export default _default;
1
+ import { ControlConfig, AudioProperties, ReactionsProperties, ViewTheParticipantListProperties } from './types';
2
+ /**
3
+ * The Controls Options Manager utilities
4
+ *
5
+ * @internal
6
+ */
7
+ declare class Utils {
8
+ /**
9
+ * Validate if enabling mute on entry can be set.
10
+ *
11
+ * @param {Array<string>} displayHints - Display Hints to use when validating.
12
+ * @returns {boolean} - True if the action is allowed.
13
+ */
14
+ static canSetMuteOnEntry(displayHints: Array<string>): boolean;
15
+ /**
16
+ * Validate if allowing unmuting can be set.
17
+ *
18
+ * @param {Array<string>} displayHints - Display Hints to use when validating.
19
+ * @returns {boolean} - True if the action is allowed.
20
+ */
21
+ static canSetDisallowUnmute(displayHints: Array<string>): boolean;
22
+ /**
23
+ * Validate if disabling mute on entry can be set.
24
+ *
25
+ * @param {Array<string>} displayHints - Display Hints to use when validating.
26
+ * @returns {boolean} - True if the action is allowed.
27
+ */
28
+ static canUnsetMuteOnEntry(displayHints: Array<string>): boolean;
29
+ /**
30
+ * Validate if enabling muting can be set.
31
+ *
32
+ * @param {Array<string>} displayHints - Display Hints to use when validating.
33
+ * @returns {boolean} - True if the action is allowed.
34
+ */
35
+ static canUnsetDisallowUnmute(displayHints: Array<string>): boolean;
36
+ /**
37
+ * Validate if muting all can be set.
38
+ *
39
+ * @param {Array<string>} displayHints - Display Hints to use when validating.
40
+ * @returns {boolean} - True if the action is allowed.
41
+ */
42
+ static canSetMuted(displayHints: Array<string>): boolean;
43
+ /**
44
+ * Validate if unmuting all can be set.
45
+ *
46
+ * @param {Array<string>} displayHints - Display Hints to use when validating.
47
+ * @returns {boolean} - True if the action is allowed.
48
+ */
49
+ static canUnsetMuted(displayHints: Array<string>): boolean;
50
+ /**
51
+ * Validate an array of hints are allowed based on a full collection of hints.
52
+ *
53
+ * @param {Object} config - Configuration Object.
54
+ * @param {Array<string>} config.requiredHints - Hints required for validation.
55
+ * @param {Array<string>} config.displayHints - All available hints.
56
+ * @returns {boolean} - True if all of the actions are allowed.
57
+ */
58
+ static hasHints(config: {
59
+ requiredHints: Array<string>;
60
+ displayHints: Array<string>;
61
+ }): boolean;
62
+ /**
63
+ * Validate if an audio-scoped control is allowed to be sent to the service.
64
+ *
65
+ * @param {ControlConfig<AudioProperties>} control - Audio control config to validate.
66
+ * @param {Array<string>} displayHints - All available hints.
67
+ * @returns {boolean} - True if all of the actions are allowed.
68
+ */
69
+ static canUpdateAudio(control: ControlConfig<AudioProperties>, displayHints: Array<string>): boolean;
70
+ /**
71
+ * Validate if an reactions-scoped control is allowed to be sent to the service.
72
+ *
73
+ * @param {ControlConfig<ReactionsProperties>} control - Reaction control config to validate.
74
+ * @param {Array<string>} displayHints - All available hints.
75
+ * @returns {boolean} - True if all of the actions are allowed.
76
+ */
77
+ static canUpdateReactions(control: ControlConfig<ReactionsProperties>, displayHints: Array<string>): boolean;
78
+ /**
79
+ * Validate if an share-control-scoped control is allowed to be sent to the service.
80
+ *
81
+ * @param {Array<string>} displayHints - All available hints.
82
+ * @returns {boolean} - True if all of the actions are allowed.
83
+ */
84
+ static canUpdateShareControl(displayHints: Array<string>): boolean;
85
+ /**
86
+ * Validate if an view-the-participants-list-scoped control is allowed to be sent to the service.
87
+ *
88
+ * @param {ControlConfig<ViewTheParticipantListProperties>} control - View Participants List control config to validate.
89
+ * @param {Array<string>} displayHints - All available hints.
90
+ * @returns {boolean} - True if all of the actions are allowed.
91
+ */
92
+ static canUpdateViewTheParticipantsList(control: ControlConfig<ViewTheParticipantListProperties>, displayHints: Array<string>): boolean;
93
+ /**
94
+ * Validate that a control can be sent to the service based on the provided
95
+ * display hints.
96
+ *
97
+ * @param {ControlConfig} control - Control to validate.
98
+ * @param {Array<string>} displayHints - All available hints.
99
+ * @returns {boolean} - True if all of the actions are allowed.
100
+ */
101
+ static canUpdate(control: ControlConfig, displayHints: Array<string>): boolean;
102
+ }
103
+ export default Utils;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/plugin-meetings",
3
- "version": "3.0.0-beta.80",
3
+ "version": "3.0.0-beta.81",
4
4
  "description": "",
5
5
  "license": "Cisco EULA (https://www.cisco.com/c/en/us/products/end-user-license-agreement.html)",
6
6
  "contributors": [
@@ -32,12 +32,12 @@
32
32
  "build": "yarn run -T tsc --declaration true --declarationDir ./dist/types"
33
33
  },
34
34
  "devDependencies": {
35
- "@webex/plugin-meetings": "3.0.0-beta.80",
36
- "@webex/test-helper-chai": "3.0.0-beta.80",
37
- "@webex/test-helper-mocha": "3.0.0-beta.80",
38
- "@webex/test-helper-mock-webex": "3.0.0-beta.80",
39
- "@webex/test-helper-retry": "3.0.0-beta.80",
40
- "@webex/test-helper-test-users": "3.0.0-beta.80",
35
+ "@webex/plugin-meetings": "3.0.0-beta.81",
36
+ "@webex/test-helper-chai": "3.0.0-beta.81",
37
+ "@webex/test-helper-mocha": "3.0.0-beta.81",
38
+ "@webex/test-helper-mock-webex": "3.0.0-beta.81",
39
+ "@webex/test-helper-retry": "3.0.0-beta.81",
40
+ "@webex/test-helper-test-users": "3.0.0-beta.81",
41
41
  "chai": "^4.3.4",
42
42
  "chai-as-promised": "^7.1.1",
43
43
  "jsdom-global": "3.0.2",
@@ -46,18 +46,18 @@
46
46
  "typescript": "^4.7.4"
47
47
  },
48
48
  "dependencies": {
49
- "@webex/common": "3.0.0-beta.80",
49
+ "@webex/common": "3.0.0-beta.81",
50
50
  "@webex/internal-media-core": "1.36.0",
51
- "@webex/internal-plugin-conversation": "3.0.0-beta.80",
52
- "@webex/internal-plugin-device": "3.0.0-beta.80",
53
- "@webex/internal-plugin-llm": "3.0.0-beta.80",
54
- "@webex/internal-plugin-mercury": "3.0.0-beta.80",
55
- "@webex/internal-plugin-metrics": "3.0.0-beta.80",
56
- "@webex/internal-plugin-support": "3.0.0-beta.80",
57
- "@webex/internal-plugin-user": "3.0.0-beta.80",
58
- "@webex/plugin-people": "3.0.0-beta.80",
59
- "@webex/plugin-rooms": "3.0.0-beta.80",
60
- "@webex/webex-core": "3.0.0-beta.80",
51
+ "@webex/internal-plugin-conversation": "3.0.0-beta.81",
52
+ "@webex/internal-plugin-device": "3.0.0-beta.81",
53
+ "@webex/internal-plugin-llm": "3.0.0-beta.81",
54
+ "@webex/internal-plugin-mercury": "3.0.0-beta.81",
55
+ "@webex/internal-plugin-metrics": "3.0.0-beta.81",
56
+ "@webex/internal-plugin-support": "3.0.0-beta.81",
57
+ "@webex/internal-plugin-user": "3.0.0-beta.81",
58
+ "@webex/plugin-people": "3.0.0-beta.81",
59
+ "@webex/plugin-rooms": "3.0.0-beta.81",
60
+ "@webex/webex-core": "3.0.0-beta.81",
61
61
  "ampersand-collection": "^2.0.2",
62
62
  "bowser": "^2.11.0",
63
63
  "btoa": "^1.2.1",
package/src/constants.ts CHANGED
@@ -797,7 +797,10 @@ export const DISPLAY_HINTS = {
797
797
  DISABLE_REACTIONS: 'DISABLE_REACTIONS',
798
798
  REACTIONS_ACTIVE: 'REACTIONS_ACTIVE',
799
799
  REACTIONS_INACTIVE: 'REACTIONS_INACTIVE',
800
+ SHARE_CONTROL: 'SHARE_CONTROL',
800
801
  ENABLE_MUTE_ON_ENTRY: 'ENABLE_MUTE_ON_ENTRY',
802
+ ENABLE_SHOW_DISPLAY_NAME: 'ENABLE_SHOW_DISPLAY_NAME',
803
+ DISABLE_SHOW_DISPLAY_NAME: 'DISABLE_SHOW_DISPLAY_NAME',
801
804
  DISABLE_MUTE_ON_ENTRY: 'DISABLE_MUTE_ON_ENTRY',
802
805
  ENABLE_HARD_MUTE: 'ENABLE_HARD_MUTE',
803
806
  DISABLE_HARD_MUTE: 'DISABLE_HARD_MUTE',
@@ -813,6 +816,10 @@ export const DISPLAY_HINTS = {
813
816
  DISABLE_ASK_FOR_HELP: 'DISABLE_ASK_FOR_HELP',
814
817
  DISABLE_BREAKOUT_PREASSIGNMENTS: 'DISABLE_BREAKOUT_PREASSIGNMENTS',
815
818
  DISABLE_LOBBY_TO_BREAKOUT: 'DISABLE_LOBBY_TO_BREAKOUT',
819
+
820
+ // participants list
821
+ DISABLE_VIEW_THE_PARTICIPANT_LIST: 'DISABLE_VIEW_THE_PARTICIPANT_LIST',
822
+ ENABLE_VIEW_THE_PARTICIPANT_LIST: 'ENABLE_VIEW_THE_PARTICIPANT_LIST',
816
823
  };
817
824
 
818
825
  export const SELF_ROLES = {
@@ -4,4 +4,13 @@ enum Setting {
4
4
  muted = 'Muted',
5
5
  }
6
6
 
7
+ enum Control {
8
+ audio = 'audio',
9
+ reactions = 'reactions',
10
+ shareControl = 'shareControl',
11
+ viewTheParticipantList = 'viewTheParticipantList',
12
+ }
13
+
14
+ export {Control, Setting};
15
+
7
16
  export default Setting;
@@ -3,7 +3,8 @@ import PermissionError from '../common/errors/permission';
3
3
  import {CONTROLS, HTTP_VERBS} from '../constants';
4
4
  import MeetingRequest from '../meeting/request';
5
5
  import LoggerProxy from '../common/logs/logger-proxy';
6
- import Setting from './enums';
6
+ import {Control, Setting} from './enums';
7
+ import {ControlConfig} from './types';
7
8
  import Util from './util';
8
9
  import {CAN_SET, CAN_UNSET, ENABLED} from './constants';
9
10
 
@@ -133,6 +134,40 @@ export default class ControlsOptionsManager {
133
134
  this.setLocusUrl(options?.locusUrl);
134
135
  }
135
136
 
137
+ /**
138
+ * Set controls for this meeting.
139
+ *
140
+ * @param {Array<ControlConfig>} controls - Spread Array of ControlConfigs
141
+ * @returns {Promise<Array<any>>}- Promise resolving if the request was successful.
142
+ */
143
+ protected update(...controls: Array<ControlConfig>) {
144
+ const payload = controls.reduce((output, control) => {
145
+ if (!Object.keys(Control).includes(control.scope)) {
146
+ throw new Error(
147
+ `updating meeting control scope "${control.scope}" is not a supported scope`
148
+ );
149
+ }
150
+
151
+ if (!Util.canUpdate(control, this.displayHints)) {
152
+ throw new PermissionError(
153
+ `updating meeting control scope "${control.scope}" not allowed, due to moderator property.`
154
+ );
155
+ }
156
+
157
+ return {
158
+ ...output,
159
+ [control.scope]: control.properties,
160
+ };
161
+ }, {});
162
+
163
+ // @ts-ignore
164
+ return this.request.request({
165
+ uri: `${this.locusUrl}/${CONTROLS}`,
166
+ body: payload,
167
+ method: HTTP_VERBS.PATCH,
168
+ });
169
+ }
170
+
136
171
  /**
137
172
  * @param {Setting} setting
138
173
  * @private
@@ -0,0 +1,49 @@
1
+ import {Control} from './enums';
2
+
3
+ export interface ControlProperties {
4
+ /**
5
+ * A list of additional properties that apply to various specific settings.
6
+ *
7
+ * @remarks
8
+ * The values stored here, per the service, are fully ambiguous, an can vary
9
+ * depending on which control scope is being configured.
10
+ */
11
+ [key: string]: boolean;
12
+ }
13
+
14
+ export interface AudioProperties {
15
+ muted?: boolean;
16
+ disallowUnmute?: boolean;
17
+ muteOnEntry?: boolean;
18
+ }
19
+
20
+ export interface ReactionsProperties {
21
+ enabled?: boolean;
22
+ showDisplayNameWithReactions?: boolean;
23
+ }
24
+
25
+ export interface ShareControlProperties {
26
+ control?: 'ANYONE' | 'MODERATOR_PRESENTER';
27
+ }
28
+
29
+ export interface ViewTheParticipantListProperties {
30
+ enabled?: boolean;
31
+ }
32
+
33
+ export type Properties =
34
+ | AudioProperties
35
+ | ReactionsProperties
36
+ | ShareControlProperties
37
+ | ViewTheParticipantListProperties;
38
+
39
+ export interface ControlConfig<Props = Properties> {
40
+ /**
41
+ * The scope of the control within this object.
42
+ */
43
+ scope: Control;
44
+
45
+ /**
46
+ * The properties to assign to this control.
47
+ */
48
+ properties: Props;
49
+ }
@@ -1,30 +1,229 @@
1
1
  import {DISPLAY_HINTS} from '../constants';
2
+ import {Control} from './enums';
3
+ import {
4
+ ControlConfig,
5
+ AudioProperties,
6
+ ReactionsProperties,
7
+ ViewTheParticipantListProperties,
8
+ } from './types';
2
9
 
3
- const canSetMuteOnEntry = (displayHints: Array<string>): boolean =>
4
- displayHints.includes(DISPLAY_HINTS.ENABLE_MUTE_ON_ENTRY);
10
+ /**
11
+ * The Controls Options Manager utilities
12
+ *
13
+ * @internal
14
+ */
15
+ class Utils {
16
+ /**
17
+ * Validate if enabling mute on entry can be set.
18
+ *
19
+ * @param {Array<string>} displayHints - Display Hints to use when validating.
20
+ * @returns {boolean} - True if the action is allowed.
21
+ */
22
+ public static canSetMuteOnEntry(displayHints: Array<string>): boolean {
23
+ return displayHints.includes(DISPLAY_HINTS.ENABLE_MUTE_ON_ENTRY);
24
+ }
5
25
 
6
- const canSetDisallowUnmute = (displayHints: Array<string>): boolean =>
7
- displayHints.includes(DISPLAY_HINTS.ENABLE_HARD_MUTE);
26
+ /**
27
+ * Validate if allowing unmuting can be set.
28
+ *
29
+ * @param {Array<string>} displayHints - Display Hints to use when validating.
30
+ * @returns {boolean} - True if the action is allowed.
31
+ */
32
+ public static canSetDisallowUnmute(displayHints: Array<string>): boolean {
33
+ return displayHints.includes(DISPLAY_HINTS.ENABLE_HARD_MUTE);
34
+ }
8
35
 
9
- const canUnsetMuteOnEntry = (displayHints: Array<string>): boolean =>
10
- displayHints.includes(DISPLAY_HINTS.DISABLE_MUTE_ON_ENTRY);
36
+ /**
37
+ * Validate if disabling mute on entry can be set.
38
+ *
39
+ * @param {Array<string>} displayHints - Display Hints to use when validating.
40
+ * @returns {boolean} - True if the action is allowed.
41
+ */
42
+ public static canUnsetMuteOnEntry(displayHints: Array<string>): boolean {
43
+ return displayHints.includes(DISPLAY_HINTS.DISABLE_MUTE_ON_ENTRY);
44
+ }
11
45
 
12
- const canUnsetDisallowUnmute = (displayHints: Array<string>): boolean =>
13
- displayHints.includes(DISPLAY_HINTS.DISABLE_HARD_MUTE);
46
+ /**
47
+ * Validate if enabling muting can be set.
48
+ *
49
+ * @param {Array<string>} displayHints - Display Hints to use when validating.
50
+ * @returns {boolean} - True if the action is allowed.
51
+ */
52
+ public static canUnsetDisallowUnmute(displayHints: Array<string>): boolean {
53
+ return displayHints.includes(DISPLAY_HINTS.DISABLE_HARD_MUTE);
54
+ }
14
55
 
15
- // 'Muted' in the context of controls options manager refers to mute/unmute all.
16
- // This was chosen because locus uses "muted" in the /controls API
17
- const canSetMuted = (displayHints: Array<string>): boolean =>
18
- displayHints.includes(DISPLAY_HINTS.MUTE_ALL);
56
+ /**
57
+ * Validate if muting all can be set.
58
+ *
59
+ * @param {Array<string>} displayHints - Display Hints to use when validating.
60
+ * @returns {boolean} - True if the action is allowed.
61
+ */
62
+ public static canSetMuted(displayHints: Array<string>): boolean {
63
+ return displayHints.includes(DISPLAY_HINTS.MUTE_ALL);
64
+ }
19
65
 
20
- const canUnsetMuted = (displayHints: Array<string>): boolean =>
21
- displayHints.includes(DISPLAY_HINTS.UNMUTE_ALL);
66
+ /**
67
+ * Validate if unmuting all can be set.
68
+ *
69
+ * @param {Array<string>} displayHints - Display Hints to use when validating.
70
+ * @returns {boolean} - True if the action is allowed.
71
+ */
72
+ public static canUnsetMuted(displayHints: Array<string>): boolean {
73
+ return displayHints.includes(DISPLAY_HINTS.UNMUTE_ALL);
74
+ }
22
75
 
23
- export default {
24
- canSetMuteOnEntry,
25
- canSetDisallowUnmute,
26
- canSetMuted,
27
- canUnsetMuteOnEntry,
28
- canUnsetDisallowUnmute,
29
- canUnsetMuted,
30
- };
76
+ /**
77
+ * Validate an array of hints are allowed based on a full collection of hints.
78
+ *
79
+ * @param {Object} config - Configuration Object.
80
+ * @param {Array<string>} config.requiredHints - Hints required for validation.
81
+ * @param {Array<string>} config.displayHints - All available hints.
82
+ * @returns {boolean} - True if all of the actions are allowed.
83
+ */
84
+ public static hasHints(config: {requiredHints: Array<string>; displayHints: Array<string>}) {
85
+ const {requiredHints, displayHints} = config;
86
+
87
+ return requiredHints.every((hint) => displayHints.includes(hint));
88
+ }
89
+
90
+ /**
91
+ * Validate if an audio-scoped control is allowed to be sent to the service.
92
+ *
93
+ * @param {ControlConfig<AudioProperties>} control - Audio control config to validate.
94
+ * @param {Array<string>} displayHints - All available hints.
95
+ * @returns {boolean} - True if all of the actions are allowed.
96
+ */
97
+ public static canUpdateAudio(
98
+ control: ControlConfig<AudioProperties>,
99
+ displayHints: Array<string>
100
+ ) {
101
+ const requiredHints = [];
102
+
103
+ if (control.properties.muted === true) {
104
+ requiredHints.push(DISPLAY_HINTS.MUTE_ALL);
105
+ }
106
+ if (control.properties.muted === false) {
107
+ requiredHints.push(DISPLAY_HINTS.UNMUTE_ALL);
108
+ }
109
+ if (control.properties.disallowUnmute === true) {
110
+ requiredHints.push(DISPLAY_HINTS.ENABLE_HARD_MUTE);
111
+ }
112
+ if (control.properties.disallowUnmute === false) {
113
+ requiredHints.push(DISPLAY_HINTS.DISABLE_HARD_MUTE);
114
+ }
115
+ if (control.properties.muteOnEntry === true) {
116
+ requiredHints.push(DISPLAY_HINTS.ENABLE_MUTE_ON_ENTRY);
117
+ }
118
+ if (control.properties.muteOnEntry === false) {
119
+ requiredHints.push(DISPLAY_HINTS.DISABLE_MUTE_ON_ENTRY);
120
+ }
121
+
122
+ return Utils.hasHints({requiredHints, displayHints});
123
+ }
124
+
125
+ /**
126
+ * Validate if an reactions-scoped control is allowed to be sent to the service.
127
+ *
128
+ * @param {ControlConfig<ReactionsProperties>} control - Reaction control config to validate.
129
+ * @param {Array<string>} displayHints - All available hints.
130
+ * @returns {boolean} - True if all of the actions are allowed.
131
+ */
132
+ public static canUpdateReactions(
133
+ control: ControlConfig<ReactionsProperties>,
134
+ displayHints: Array<string>
135
+ ) {
136
+ const requiredHints = [];
137
+
138
+ if (control.properties.enabled === true) {
139
+ requiredHints.push(DISPLAY_HINTS.ENABLE_REACTIONS);
140
+ }
141
+ if (control.properties.enabled === false) {
142
+ requiredHints.push(DISPLAY_HINTS.DISABLE_REACTIONS);
143
+ }
144
+ if (control.properties.showDisplayNameWithReactions === true) {
145
+ requiredHints.push(DISPLAY_HINTS.ENABLE_SHOW_DISPLAY_NAME);
146
+ }
147
+ if (control.properties.showDisplayNameWithReactions === false) {
148
+ requiredHints.push(DISPLAY_HINTS.DISABLE_SHOW_DISPLAY_NAME);
149
+ }
150
+
151
+ return Utils.hasHints({requiredHints, displayHints});
152
+ }
153
+
154
+ /**
155
+ * Validate if an share-control-scoped control is allowed to be sent to the service.
156
+ *
157
+ * @param {Array<string>} displayHints - All available hints.
158
+ * @returns {boolean} - True if all of the actions are allowed.
159
+ */
160
+ public static canUpdateShareControl(displayHints: Array<string>) {
161
+ return Utils.hasHints({requiredHints: [DISPLAY_HINTS.SHARE_CONTROL], displayHints});
162
+ }
163
+
164
+ /**
165
+ * Validate if an view-the-participants-list-scoped control is allowed to be sent to the service.
166
+ *
167
+ * @param {ControlConfig<ViewTheParticipantListProperties>} control - View Participants List control config to validate.
168
+ * @param {Array<string>} displayHints - All available hints.
169
+ * @returns {boolean} - True if all of the actions are allowed.
170
+ */
171
+ public static canUpdateViewTheParticipantsList(
172
+ control: ControlConfig<ViewTheParticipantListProperties>,
173
+ displayHints: Array<string>
174
+ ) {
175
+ const requiredHints = [];
176
+
177
+ if (control.properties.enabled === true) {
178
+ requiredHints.push(DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST);
179
+ }
180
+ if (control.properties.enabled === false) {
181
+ requiredHints.push(DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST);
182
+ }
183
+
184
+ return Utils.hasHints({requiredHints, displayHints});
185
+ }
186
+
187
+ /**
188
+ * Validate that a control can be sent to the service based on the provided
189
+ * display hints.
190
+ *
191
+ * @param {ControlConfig} control - Control to validate.
192
+ * @param {Array<string>} displayHints - All available hints.
193
+ * @returns {boolean} - True if all of the actions are allowed.
194
+ */
195
+ public static canUpdate(control: ControlConfig, displayHints: Array<string>) {
196
+ let determinant: boolean;
197
+
198
+ switch (control.scope) {
199
+ case Control.audio:
200
+ determinant = Utils.canUpdateAudio(control as ControlConfig<AudioProperties>, displayHints);
201
+ break;
202
+
203
+ case Control.reactions:
204
+ determinant = Utils.canUpdateReactions(
205
+ control as ControlConfig<ReactionsProperties>,
206
+ displayHints
207
+ );
208
+ break;
209
+
210
+ case Control.shareControl:
211
+ determinant = Utils.canUpdateShareControl(displayHints);
212
+ break;
213
+
214
+ case Control.viewTheParticipantList:
215
+ determinant = Utils.canUpdateViewTheParticipantsList(
216
+ control as ControlConfig<ViewTheParticipantListProperties>,
217
+ displayHints
218
+ );
219
+ break;
220
+
221
+ default:
222
+ determinant = false;
223
+ }
224
+
225
+ return determinant;
226
+ }
227
+ }
228
+
229
+ export default Utils;
@@ -1,4 +1,5 @@
1
1
  import ControlsOptionsManager from '@webex/plugin-meetings/src/controls-options-manager';
2
+ import Util from '@webex/plugin-meetings/src/controls-options-manager/util';
2
3
  import sinon from 'sinon';
3
4
  import {assert} from '@webex/test-helper-chai';
4
5
  import { HTTP_VERBS } from '@webex/plugin-meetings/src/constants';
@@ -120,6 +121,81 @@ describe('plugin-meetings', () => {
120
121
  });
121
122
  });
122
123
 
124
+ describe('update()', () => {
125
+ let manager;
126
+
127
+ beforeEach(() => {
128
+ request = {
129
+ request: sinon.stub().resolves(),
130
+ };
131
+
132
+ manager = new ControlsOptionsManager(request);
133
+
134
+ manager.set({
135
+ locusUrl: 'test/id',
136
+ displayHints: [],
137
+ });
138
+ });
139
+
140
+ it('should throw an error if the scope is not supported', () => {
141
+ const scope = 'invalid';
142
+
143
+ assert.throws(() => manager.update({scope}));
144
+ });
145
+
146
+ it('should throw an error if canUpdate returns false', () => {
147
+ const restorable = Util.canUpdate;
148
+ Util.canUpdate = sinon.stub().returns(false);
149
+
150
+ const scope = 'audio';
151
+
152
+ assert.throws(() => manager.update({scope}));
153
+ Util.canUpdate = restorable;
154
+ });
155
+
156
+ it('should call request with a body that includes formatted locus details', () => {
157
+ const restorable = Util.canUpdate;
158
+ Util.canUpdate = sinon.stub().returns(true);
159
+
160
+ const audio = {scope: 'audio', properties: {a: 1, b: 2}};
161
+ const reactions = {scope: 'reactions', properties: {c: 3, d: 4}};
162
+
163
+ return manager.update(audio, reactions)
164
+ .then(() => {
165
+ assert.calledWith(request.request, {
166
+ uri: 'test/id/controls',
167
+ body: {
168
+ audio: audio.properties,
169
+ reactions: reactions.properties,
170
+ },
171
+ method: HTTP_VERBS.PATCH,
172
+ });
173
+
174
+ Util.canUpdate = restorable;
175
+ });
176
+ });
177
+
178
+ it('should check if the user can update for each provided control config', () => {
179
+ const restorable = Util.canUpdate;
180
+ Util.canUpdate = sinon.stub().returns(true);
181
+
182
+ const audio = {scope: 'audio', properties: {a: 1, b: 2}};
183
+ const reactions = {scope: 'reactions', properties: {c: 3, d: 4}};
184
+ const controls = [audio, reactions];
185
+
186
+ return manager.update(...controls)
187
+ .then(() => {
188
+ assert.callCount(Util.canUpdate, controls.length);
189
+
190
+ controls.forEach((control) => {
191
+ assert.calledWith(Util.canUpdate, control, manager.displayHints);
192
+ });
193
+
194
+ Util.canUpdate = restorable;
195
+ });
196
+ });
197
+ });
198
+
123
199
  describe('Mute/Unmute All', () => {
124
200
  let manager;
125
201
  beforeEach(() => {