@webex/plugin-meetings 3.12.0-next.72 → 3.12.0-next.74
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.
- package/dist/aiEnableRequest/index.js +1 -1
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/constants.js +4 -1
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/index.js +29 -5
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/infoUtils.js +36 -5
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +3 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +21 -8
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/util.js +9 -0
- package/dist/meeting/util.js.map +1 -1
- package/dist/types/constants.d.ts +3 -0
- package/dist/types/controls-options-manager/index.d.ts +6 -0
- package/dist/types/locus-info/infoUtils.d.ts +8 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +2 -0
- package/dist/types/meeting/index.d.ts +1 -0
- package/dist/types/meeting/util.d.ts +1 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +1 -1
- package/src/constants.ts +3 -0
- package/src/controls-options-manager/index.ts +40 -4
- package/src/locus-info/infoUtils.ts +41 -6
- package/src/meeting/in-meeting-actions.ts +4 -0
- package/src/meeting/index.ts +10 -0
- package/src/meeting/util.ts +12 -0
- package/test/unit/spec/controls-options-manager/index.js +104 -0
- package/test/unit/spec/locus-info/index.js +12 -0
- package/test/unit/spec/locus-info/infoUtils.js +87 -0
- package/test/unit/spec/meeting/in-meeting-actions.ts +2 -0
- package/test/unit/spec/meeting/utils.js +49 -0
- package/test/unit/spec/meetings/index.js +3 -0
|
@@ -4,7 +4,7 @@ import PermissionError from '../common/errors/permission';
|
|
|
4
4
|
import MeetingRequest from '../meeting/request';
|
|
5
5
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
6
6
|
import {Control, Setting} from './enums';
|
|
7
|
-
import {ControlConfig} from './types';
|
|
7
|
+
import {ControlConfig, ViewTheParticipantListProperties} from './types';
|
|
8
8
|
import Util from './util';
|
|
9
9
|
import {CAN_SET, CAN_UNSET, ENABLED} from './constants';
|
|
10
10
|
|
|
@@ -56,6 +56,10 @@ export default class ControlsOptionsManager {
|
|
|
56
56
|
*/
|
|
57
57
|
private mainLocusUrl: string;
|
|
58
58
|
|
|
59
|
+
private getControls: () => Record<string, any> = () => ({});
|
|
60
|
+
|
|
61
|
+
private isWebinar: () => boolean = () => false;
|
|
62
|
+
|
|
59
63
|
/**
|
|
60
64
|
* @param {MeetingRequest} request
|
|
61
65
|
* @param {Object} options
|
|
@@ -67,6 +71,8 @@ export default class ControlsOptionsManager {
|
|
|
67
71
|
options?: {
|
|
68
72
|
locusUrl: string;
|
|
69
73
|
displayHints?: Array<string>;
|
|
74
|
+
getControls?: () => Record<string, any>;
|
|
75
|
+
isWebinar?: () => boolean;
|
|
70
76
|
}
|
|
71
77
|
) {
|
|
72
78
|
this.initialize(request);
|
|
@@ -89,7 +95,12 @@ export default class ControlsOptionsManager {
|
|
|
89
95
|
* @public
|
|
90
96
|
* @memberof ControlsOptionsManager
|
|
91
97
|
*/
|
|
92
|
-
public set(options?: {
|
|
98
|
+
public set(options?: {
|
|
99
|
+
locusUrl: string;
|
|
100
|
+
displayHints?: Array<string>;
|
|
101
|
+
getControls?: () => Record<string, any>;
|
|
102
|
+
isWebinar?: () => boolean;
|
|
103
|
+
}) {
|
|
93
104
|
this.extract(options);
|
|
94
105
|
}
|
|
95
106
|
|
|
@@ -141,9 +152,20 @@ export default class ControlsOptionsManager {
|
|
|
141
152
|
* @private
|
|
142
153
|
* @memberof ControlsOptionsManager
|
|
143
154
|
*/
|
|
144
|
-
private extract(options?: {
|
|
155
|
+
private extract(options?: {
|
|
156
|
+
locusUrl: string;
|
|
157
|
+
displayHints?: Array<string>;
|
|
158
|
+
getControls?: () => Record<string, any>;
|
|
159
|
+
isWebinar?: () => boolean;
|
|
160
|
+
}) {
|
|
145
161
|
this.setDisplayHints(options?.displayHints);
|
|
146
162
|
this.setLocusUrl(options?.locusUrl);
|
|
163
|
+
if (options?.getControls) {
|
|
164
|
+
this.getControls = options.getControls;
|
|
165
|
+
}
|
|
166
|
+
if (options?.isWebinar) {
|
|
167
|
+
this.isWebinar = options.isWebinar;
|
|
168
|
+
}
|
|
147
169
|
}
|
|
148
170
|
|
|
149
171
|
/**
|
|
@@ -172,8 +194,22 @@ export default class ControlsOptionsManager {
|
|
|
172
194
|
);
|
|
173
195
|
}
|
|
174
196
|
|
|
197
|
+
let {properties} = control;
|
|
198
|
+
|
|
199
|
+
if (control.scope === Control.viewTheParticipantList) {
|
|
200
|
+
const props = properties as ViewTheParticipantListProperties;
|
|
201
|
+
const current = this.getControls()?.viewTheParticipantList;
|
|
202
|
+
properties = {
|
|
203
|
+
enabled: props.enabled ?? current?.enabled ?? false,
|
|
204
|
+
...(this.isWebinar() && {
|
|
205
|
+
panelistEnabled: props.panelistEnabled ?? current?.panelistEnabled ?? false,
|
|
206
|
+
attendeeCount: props.attendeeCount ?? Boolean(current?.attendeeCount) ?? false,
|
|
207
|
+
}),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
175
211
|
return {
|
|
176
|
-
[control.scope]:
|
|
212
|
+
[control.scope]: properties,
|
|
177
213
|
};
|
|
178
214
|
});
|
|
179
215
|
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import {SELF_ROLES, DISPLAY_HINTS, INTERSTITIAL_DISPLAY_HINTS} from '../constants';
|
|
2
2
|
|
|
3
|
+
// these values have to match what Locus sends us
|
|
4
|
+
export enum DisplayHintSection {
|
|
5
|
+
JOINED = 'joined',
|
|
6
|
+
MODERATOR = 'moderator',
|
|
7
|
+
COHOST = 'coHost',
|
|
8
|
+
PRESENTER = 'presenter',
|
|
9
|
+
PANELIST = 'panelist',
|
|
10
|
+
ATTENDEE = 'attendee',
|
|
11
|
+
}
|
|
12
|
+
|
|
3
13
|
const InfoUtils: any = {};
|
|
4
14
|
|
|
5
15
|
InfoUtils.parse = (info, roles, isJoined = true) => {
|
|
@@ -7,6 +17,9 @@ InfoUtils.parse = (info, roles, isJoined = true) => {
|
|
|
7
17
|
policy: InfoUtils.parsePolicy(info),
|
|
8
18
|
moderator: InfoUtils.parseModerator(info),
|
|
9
19
|
coHost: InfoUtils.parseCoHost(info),
|
|
20
|
+
presenter: InfoUtils.parsePresenter(info),
|
|
21
|
+
panelist: InfoUtils.parsePanelist(info),
|
|
22
|
+
attendee: InfoUtils.parseAttendee(info),
|
|
10
23
|
};
|
|
11
24
|
|
|
12
25
|
let userDisplayHints = isJoined
|
|
@@ -27,6 +40,18 @@ InfoUtils.parse = (info, roles, isJoined = true) => {
|
|
|
27
40
|
userDisplayHints = {...userDisplayHints, ...parsed.moderator};
|
|
28
41
|
}
|
|
29
42
|
|
|
43
|
+
if (roles.includes(SELF_ROLES.PRESENTER)) {
|
|
44
|
+
userDisplayHints = {...userDisplayHints, ...parsed.presenter};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (roles.includes(SELF_ROLES.PANELIST)) {
|
|
48
|
+
userDisplayHints = {...userDisplayHints, ...parsed.panelist};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (roles.includes(SELF_ROLES.ATTENDEE)) {
|
|
52
|
+
userDisplayHints = {...userDisplayHints, ...parsed.attendee};
|
|
53
|
+
}
|
|
54
|
+
|
|
30
55
|
parsed.userDisplayHints = Object.keys(userDisplayHints);
|
|
31
56
|
|
|
32
57
|
if (info.sipUri) {
|
|
@@ -44,8 +69,8 @@ InfoUtils.parse = (info, roles, isJoined = true) => {
|
|
|
44
69
|
return parsed;
|
|
45
70
|
};
|
|
46
71
|
|
|
47
|
-
InfoUtils.parseDisplayHintSection = (info, displayHintKey) => {
|
|
48
|
-
const displayHints = {};
|
|
72
|
+
InfoUtils.parseDisplayHintSection = (info: any, displayHintKey: DisplayHintSection) => {
|
|
73
|
+
const displayHints: Record<string, boolean> = {};
|
|
49
74
|
|
|
50
75
|
if (
|
|
51
76
|
info &&
|
|
@@ -53,7 +78,7 @@ InfoUtils.parseDisplayHintSection = (info, displayHintKey) => {
|
|
|
53
78
|
info.displayHints[displayHintKey] &&
|
|
54
79
|
info.displayHints[displayHintKey].length > 0
|
|
55
80
|
) {
|
|
56
|
-
info.displayHints[displayHintKey].forEach((key) => {
|
|
81
|
+
info.displayHints[displayHintKey].forEach((key: any) => {
|
|
57
82
|
displayHints[key] = true;
|
|
58
83
|
});
|
|
59
84
|
}
|
|
@@ -61,20 +86,30 @@ InfoUtils.parseDisplayHintSection = (info, displayHintKey) => {
|
|
|
61
86
|
return displayHints;
|
|
62
87
|
};
|
|
63
88
|
|
|
64
|
-
InfoUtils.parsePolicy = (info) =>
|
|
89
|
+
InfoUtils.parsePolicy = (info) =>
|
|
90
|
+
InfoUtils.parseDisplayHintSection(info, DisplayHintSection.JOINED);
|
|
65
91
|
|
|
66
92
|
InfoUtils.parseModerator = (info) => {
|
|
67
|
-
const displayHints = InfoUtils.parseDisplayHintSection(info,
|
|
93
|
+
const displayHints = InfoUtils.parseDisplayHintSection(info, DisplayHintSection.MODERATOR);
|
|
68
94
|
|
|
69
95
|
return {...displayHints, [DISPLAY_HINTS.LOWER_SOMEONE_ELSES_HAND]: true};
|
|
70
96
|
};
|
|
71
97
|
|
|
72
98
|
InfoUtils.parseCoHost = (info) => {
|
|
73
|
-
const displayHints = InfoUtils.parseDisplayHintSection(info,
|
|
99
|
+
const displayHints = InfoUtils.parseDisplayHintSection(info, DisplayHintSection.COHOST);
|
|
74
100
|
|
|
75
101
|
return {...displayHints, [DISPLAY_HINTS.LOWER_SOMEONE_ELSES_HAND]: true};
|
|
76
102
|
};
|
|
77
103
|
|
|
104
|
+
InfoUtils.parsePresenter = (info) =>
|
|
105
|
+
InfoUtils.parseDisplayHintSection(info, DisplayHintSection.PRESENTER);
|
|
106
|
+
|
|
107
|
+
InfoUtils.parsePanelist = (info) =>
|
|
108
|
+
InfoUtils.parseDisplayHintSection(info, DisplayHintSection.PANELIST);
|
|
109
|
+
|
|
110
|
+
InfoUtils.parseAttendee = (info) =>
|
|
111
|
+
InfoUtils.parseDisplayHintSection(info, DisplayHintSection.ATTENDEE);
|
|
112
|
+
|
|
78
113
|
InfoUtils.isLocked = (policy) => policy.LOCK_STATUS_LOCKED || false;
|
|
79
114
|
|
|
80
115
|
InfoUtils.isUnlocked = (policy) => policy.LOCK_STATUS_UNLOCKED || false;
|
|
@@ -121,6 +121,7 @@ interface IInMeetingActions {
|
|
|
121
121
|
canAttendeeRequestAiAssistantEnabled?: boolean;
|
|
122
122
|
isAttendeeRequestAiAssistantDeclinedAll?: boolean;
|
|
123
123
|
isAnonymizeDisplayNamesEnabled?: boolean;
|
|
124
|
+
canViewTheParticipantList?: boolean;
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
/**
|
|
@@ -349,6 +350,8 @@ export default class InMeetingActions implements IInMeetingActions {
|
|
|
349
350
|
|
|
350
351
|
isAnonymizeDisplayNamesEnabled = null;
|
|
351
352
|
|
|
353
|
+
canViewTheParticipantList = null;
|
|
354
|
+
|
|
352
355
|
/**
|
|
353
356
|
* Returns all meeting action options
|
|
354
357
|
* @returns {Object}
|
|
@@ -464,6 +467,7 @@ export default class InMeetingActions implements IInMeetingActions {
|
|
|
464
467
|
canAttendeeRequestAiAssistantEnabled: this.canAttendeeRequestAiAssistantEnabled,
|
|
465
468
|
isAttendeeRequestAiAssistantDeclinedAll: this.isAttendeeRequestAiAssistantDeclinedAll,
|
|
466
469
|
isAnonymizeDisplayNamesEnabled: this.isAnonymizeDisplayNamesEnabled,
|
|
470
|
+
canViewTheParticipantList: this.canViewTheParticipantList,
|
|
467
471
|
});
|
|
468
472
|
|
|
469
473
|
/**
|
package/src/meeting/index.ts
CHANGED
|
@@ -665,6 +665,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
665
665
|
joinedWith?: any;
|
|
666
666
|
selfId?: string;
|
|
667
667
|
roles: any[];
|
|
668
|
+
canNotViewTheParticipantList?: boolean;
|
|
668
669
|
// ... there is more ... see SelfUtils.parse()
|
|
669
670
|
// end of the group
|
|
670
671
|
locusMediaRequest?: LocusMediaRequest;
|
|
@@ -1567,6 +1568,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1567
1568
|
this.controlsOptionsManager = new ControlsOptionsManager(this.meetingRequest, {
|
|
1568
1569
|
locusUrl: this.locusInfo?.url,
|
|
1569
1570
|
displayHints: [],
|
|
1571
|
+
getControls: () => this.locusInfo?.controls,
|
|
1572
|
+
isWebinar: () => this.locusInfo?.info?.isWebinar,
|
|
1570
1573
|
});
|
|
1571
1574
|
|
|
1572
1575
|
this.setUpLocusInfoListeners();
|
|
@@ -3857,6 +3860,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3857
3860
|
});
|
|
3858
3861
|
|
|
3859
3862
|
this.locusInfo.on(LOCUSINFO.EVENTS.SELF_CANNOT_VIEW_PARTICIPANT_LIST_CHANGE, (payload) => {
|
|
3863
|
+
// canViewTheParticipantList meeting action depends on this value, so we need to update meeting actions
|
|
3864
|
+
this.updateMeetingActions();
|
|
3865
|
+
|
|
3860
3866
|
Trigger.trigger(
|
|
3861
3867
|
this,
|
|
3862
3868
|
{
|
|
@@ -4658,6 +4664,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4658
4664
|
isAnonymizeDisplayNamesEnabled: MeetingUtil.isAnonymizeDisplayNamesEnabled(
|
|
4659
4665
|
this.userDisplayHints
|
|
4660
4666
|
),
|
|
4667
|
+
canViewTheParticipantList: MeetingUtil.canViewTheParticipantList(
|
|
4668
|
+
this.userDisplayHints,
|
|
4669
|
+
this.canNotViewTheParticipantList ?? false
|
|
4670
|
+
),
|
|
4661
4671
|
}) || changed;
|
|
4662
4672
|
}
|
|
4663
4673
|
if (changed) {
|
package/src/meeting/util.ts
CHANGED
|
@@ -949,6 +949,18 @@ const MeetingUtil = {
|
|
|
949
949
|
isAnonymizeDisplayNamesEnabled: (displayHints) =>
|
|
950
950
|
displayHints.includes(DISPLAY_HINTS.ANONYMOUS_DISPLAY_NAMES_ENABLED),
|
|
951
951
|
|
|
952
|
+
canViewTheParticipantList: (displayHints, canNotViewTheParticipantList: boolean) => {
|
|
953
|
+
if (!displayHints.includes(DISPLAY_HINTS.VIEW_THE_PARTICIPANT_LIST)) {
|
|
954
|
+
return false;
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
if (canNotViewTheParticipantList) {
|
|
958
|
+
return false;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
return displayHints.includes(DISPLAY_HINTS.CAN_VIEW_THE_PARTICIPANT_LIST);
|
|
962
|
+
},
|
|
963
|
+
|
|
952
964
|
selfSupportsFeature: (feature: SELF_POLICY, userPolicies: Record<SELF_POLICY, boolean>) => {
|
|
953
965
|
if (!userPolicies) {
|
|
954
966
|
return true;
|
|
@@ -319,6 +319,110 @@ describe('plugin-meetings', () => {
|
|
|
319
319
|
Util.canUpdate = restorable;
|
|
320
320
|
});
|
|
321
321
|
});
|
|
322
|
+
|
|
323
|
+
describe('viewTheParticipantList fill-in', () => {
|
|
324
|
+
let restorable;
|
|
325
|
+
|
|
326
|
+
afterEach(() => {
|
|
327
|
+
Util.canUpdate = restorable;
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
describe('when meeting is a webinar', () => {
|
|
331
|
+
beforeEach(() => {
|
|
332
|
+
restorable = Util.canUpdate;
|
|
333
|
+
Util.canUpdate = sinon.stub().returns(true);
|
|
334
|
+
manager.set({
|
|
335
|
+
locusUrl: 'test/id',
|
|
336
|
+
displayHints: [],
|
|
337
|
+
getControls: () => ({viewTheParticipantList: {enabled: true, panelistEnabled: true, attendeeCount: true}}),
|
|
338
|
+
isWebinar: () => true,
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it('should fill in all undefined properties from current state', () => {
|
|
343
|
+
const control = {scope: 'viewTheParticipantList', properties: {}};
|
|
344
|
+
|
|
345
|
+
return manager.update(control).then(() => {
|
|
346
|
+
assert.calledOnceWithExactly(request.locusDeltaRequest, {
|
|
347
|
+
uri: 'test/id/controls',
|
|
348
|
+
body: {
|
|
349
|
+
viewTheParticipantList: {enabled: true, panelistEnabled: true, attendeeCount: true},
|
|
350
|
+
},
|
|
351
|
+
method: HTTP_VERBS.PATCH,
|
|
352
|
+
});
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
it('should keep explicitly provided properties and fill in the rest', () => {
|
|
357
|
+
const control = {scope: 'viewTheParticipantList', properties: {enabled: false}};
|
|
358
|
+
|
|
359
|
+
return manager.update(control).then(() => {
|
|
360
|
+
assert.calledOnceWithExactly(request.locusDeltaRequest, {
|
|
361
|
+
uri: 'test/id/controls',
|
|
362
|
+
body: {
|
|
363
|
+
viewTheParticipantList: {enabled: false, panelistEnabled: true, attendeeCount: true},
|
|
364
|
+
},
|
|
365
|
+
method: HTTP_VERBS.PATCH,
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
it('should not fill in properties when all are explicitly provided', () => {
|
|
371
|
+
const control = {scope: 'viewTheParticipantList', properties: {enabled: false, panelistEnabled: false, attendeeCount: false}};
|
|
372
|
+
|
|
373
|
+
return manager.update(control).then(() => {
|
|
374
|
+
assert.calledOnceWithExactly(request.locusDeltaRequest, {
|
|
375
|
+
uri: 'test/id/controls',
|
|
376
|
+
body: {
|
|
377
|
+
viewTheParticipantList: {enabled: false, panelistEnabled: false, attendeeCount: false},
|
|
378
|
+
},
|
|
379
|
+
method: HTTP_VERBS.PATCH,
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
describe('when meeting is not a webinar', () => {
|
|
386
|
+
beforeEach(() => {
|
|
387
|
+
restorable = Util.canUpdate;
|
|
388
|
+
Util.canUpdate = sinon.stub().returns(true);
|
|
389
|
+
manager.set({
|
|
390
|
+
locusUrl: 'test/id',
|
|
391
|
+
displayHints: [],
|
|
392
|
+
getControls: () => ({viewTheParticipantList: {enabled: true, panelistEnabled: true, attendeeCount: true}}),
|
|
393
|
+
isWebinar: () => false,
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
it('should only send enabled property', () => {
|
|
398
|
+
const control = {scope: 'viewTheParticipantList', properties: {}};
|
|
399
|
+
|
|
400
|
+
return manager.update(control).then(() => {
|
|
401
|
+
assert.calledOnceWithExactly(request.locusDeltaRequest, {
|
|
402
|
+
uri: 'test/id/controls',
|
|
403
|
+
body: {
|
|
404
|
+
viewTheParticipantList: {enabled: true},
|
|
405
|
+
},
|
|
406
|
+
method: HTTP_VERBS.PATCH,
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
it('should not include panelistEnabled or attendeeCount even if explicitly provided', () => {
|
|
412
|
+
const control = {scope: 'viewTheParticipantList', properties: {enabled: false, panelistEnabled: true, attendeeCount: true}};
|
|
413
|
+
|
|
414
|
+
return manager.update(control).then(() => {
|
|
415
|
+
assert.calledOnceWithExactly(request.locusDeltaRequest, {
|
|
416
|
+
uri: 'test/id/controls',
|
|
417
|
+
body: {
|
|
418
|
+
viewTheParticipantList: {enabled: false},
|
|
419
|
+
},
|
|
420
|
+
method: HTTP_VERBS.PATCH,
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
});
|
|
425
|
+
});
|
|
322
426
|
});
|
|
323
427
|
|
|
324
428
|
describe('Mute/Unmute All', () => {
|
|
@@ -2856,6 +2856,7 @@ describe('plugin-meetings', () => {
|
|
|
2856
2856
|
|
|
2857
2857
|
// set the info initially as locusInfo.info starts as undefined
|
|
2858
2858
|
expectedMeeting = {
|
|
2859
|
+
attendee: {},
|
|
2859
2860
|
coHost: {
|
|
2860
2861
|
LOWER_SOMEONE_ELSES_HAND: true,
|
|
2861
2862
|
},
|
|
@@ -2864,10 +2865,12 @@ describe('plugin-meetings', () => {
|
|
|
2864
2865
|
moderator: {
|
|
2865
2866
|
LOWER_SOMEONE_ELSES_HAND: true,
|
|
2866
2867
|
},
|
|
2868
|
+
panelist: {},
|
|
2867
2869
|
policy: {
|
|
2868
2870
|
LOCK_STATUS_UNLOCKED: true,
|
|
2869
2871
|
ROSTER_IN_MEETING: true,
|
|
2870
2872
|
},
|
|
2873
|
+
presenter: {},
|
|
2871
2874
|
userDisplayHints: ['ROSTER_IN_MEETING', 'LOCK_STATUS_UNLOCKED'],
|
|
2872
2875
|
};
|
|
2873
2876
|
locusInfo.updateMeetingInfo(initialInfo, self);
|
|
@@ -2882,6 +2885,7 @@ describe('plugin-meetings', () => {
|
|
|
2882
2885
|
|
|
2883
2886
|
// Updating with different info should trigger the event
|
|
2884
2887
|
expectedMeeting = {
|
|
2888
|
+
attendee: {},
|
|
2885
2889
|
coHost: {
|
|
2886
2890
|
LOWER_SOMEONE_ELSES_HAND: true,
|
|
2887
2891
|
LOCK_CONTROL_LOCK: true,
|
|
@@ -2891,10 +2895,12 @@ describe('plugin-meetings', () => {
|
|
|
2891
2895
|
moderator: {
|
|
2892
2896
|
LOWER_SOMEONE_ELSES_HAND: true,
|
|
2893
2897
|
},
|
|
2898
|
+
panelist: {},
|
|
2894
2899
|
policy: {
|
|
2895
2900
|
LOCK_STATUS_UNLOCKED: true,
|
|
2896
2901
|
ROSTER_IN_MEETING: true,
|
|
2897
2902
|
},
|
|
2903
|
+
presenter: {},
|
|
2898
2904
|
userDisplayHints: ['ROSTER_IN_MEETING', 'LOCK_STATUS_UNLOCKED'],
|
|
2899
2905
|
};
|
|
2900
2906
|
locusInfo.updateMeetingInfo(newInfo, self);
|
|
@@ -2903,6 +2909,7 @@ describe('plugin-meetings', () => {
|
|
|
2903
2909
|
|
|
2904
2910
|
// update it with the same info
|
|
2905
2911
|
expectedMeeting = {
|
|
2912
|
+
attendee: {},
|
|
2906
2913
|
coHost: {
|
|
2907
2914
|
LOWER_SOMEONE_ELSES_HAND: true,
|
|
2908
2915
|
LOCK_CONTROL_LOCK: true,
|
|
@@ -2912,10 +2919,12 @@ describe('plugin-meetings', () => {
|
|
|
2912
2919
|
moderator: {
|
|
2913
2920
|
LOWER_SOMEONE_ELSES_HAND: true,
|
|
2914
2921
|
},
|
|
2922
|
+
panelist: {},
|
|
2915
2923
|
policy: {
|
|
2916
2924
|
LOCK_STATUS_UNLOCKED: true,
|
|
2917
2925
|
ROSTER_IN_MEETING: true,
|
|
2918
2926
|
},
|
|
2927
|
+
presenter: {},
|
|
2919
2928
|
userDisplayHints: ['ROSTER_IN_MEETING', 'LOCK_STATUS_UNLOCKED'],
|
|
2920
2929
|
};
|
|
2921
2930
|
locusInfo.updateMeetingInfo(newInfo, self);
|
|
@@ -2930,6 +2939,7 @@ describe('plugin-meetings', () => {
|
|
|
2930
2939
|
hasRole: true,
|
|
2931
2940
|
});
|
|
2932
2941
|
expectedMeeting = {
|
|
2942
|
+
attendee: {},
|
|
2933
2943
|
coHost: {
|
|
2934
2944
|
LOWER_SOMEONE_ELSES_HAND: true,
|
|
2935
2945
|
LOCK_CONTROL_LOCK: true,
|
|
@@ -2939,10 +2949,12 @@ describe('plugin-meetings', () => {
|
|
|
2939
2949
|
moderator: {
|
|
2940
2950
|
LOWER_SOMEONE_ELSES_HAND: true,
|
|
2941
2951
|
},
|
|
2952
|
+
panelist: {},
|
|
2942
2953
|
policy: {
|
|
2943
2954
|
LOCK_STATUS_UNLOCKED: true,
|
|
2944
2955
|
ROSTER_IN_MEETING: true,
|
|
2945
2956
|
},
|
|
2957
|
+
presenter: {},
|
|
2946
2958
|
userDisplayHints: [
|
|
2947
2959
|
'ROSTER_IN_MEETING',
|
|
2948
2960
|
'LOCK_STATUS_UNLOCKED',
|
|
@@ -9,6 +9,9 @@ describe('plugin-meetings', () => {
|
|
|
9
9
|
moderator: ['HINT_1', 'HINT_2'],
|
|
10
10
|
joined: ['HINT_3', 'VOIP_IS_ENABLED'],
|
|
11
11
|
coHost: ['HINT_4'],
|
|
12
|
+
presenter: ['HINT_5'],
|
|
13
|
+
panelist: ['HINT_6'],
|
|
14
|
+
attendee: ['HINT_7'],
|
|
12
15
|
},
|
|
13
16
|
};
|
|
14
17
|
|
|
@@ -30,6 +33,9 @@ describe('plugin-meetings', () => {
|
|
|
30
33
|
policy: {HINT_3: true, VOIP_IS_ENABLED: true},
|
|
31
34
|
moderator: {HINT_1: true, HINT_2: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
32
35
|
coHost: {HINT_4: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
36
|
+
presenter: {HINT_5: true},
|
|
37
|
+
panelist: {HINT_6: true},
|
|
38
|
+
attendee: {HINT_7: true},
|
|
33
39
|
userDisplayHints: [
|
|
34
40
|
'HINT_3',
|
|
35
41
|
'VOIP_IS_ENABLED',
|
|
@@ -43,6 +49,9 @@ describe('plugin-meetings', () => {
|
|
|
43
49
|
policy: {HINT_3: true, VOIP_IS_ENABLED: true},
|
|
44
50
|
moderator: {HINT_1: true, HINT_2: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
45
51
|
coHost: {HINT_4: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
52
|
+
presenter: {HINT_5: true},
|
|
53
|
+
panelist: {HINT_6: true},
|
|
54
|
+
attendee: {HINT_7: true},
|
|
46
55
|
userDisplayHints: [
|
|
47
56
|
'HINT_3',
|
|
48
57
|
'VOIP_IS_ENABLED',
|
|
@@ -57,6 +66,9 @@ describe('plugin-meetings', () => {
|
|
|
57
66
|
policy: {HINT_3: true, VOIP_IS_ENABLED: true},
|
|
58
67
|
moderator: {HINT_1: true, HINT_2: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
59
68
|
coHost: {HINT_4: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
69
|
+
presenter: {HINT_5: true},
|
|
70
|
+
panelist: {HINT_6: true},
|
|
71
|
+
attendee: {HINT_7: true},
|
|
60
72
|
userDisplayHints: ['HINT_3', 'VOIP_IS_ENABLED', 'HINT_4', 'LOWER_SOMEONE_ELSES_HAND'],
|
|
61
73
|
});
|
|
62
74
|
|
|
@@ -64,6 +76,9 @@ describe('plugin-meetings', () => {
|
|
|
64
76
|
policy: {HINT_3: true, VOIP_IS_ENABLED: true},
|
|
65
77
|
moderator: {HINT_1: true, HINT_2: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
66
78
|
coHost: {HINT_4: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
79
|
+
presenter: {HINT_5: true},
|
|
80
|
+
panelist: {HINT_6: true},
|
|
81
|
+
attendee: {HINT_7: true},
|
|
67
82
|
userDisplayHints: ['HINT_3', 'VOIP_IS_ENABLED'],
|
|
68
83
|
});
|
|
69
84
|
});
|
|
@@ -73,6 +88,9 @@ describe('plugin-meetings', () => {
|
|
|
73
88
|
policy: {HINT_3: true, VOIP_IS_ENABLED: true},
|
|
74
89
|
moderator: {HINT_1: true, HINT_2: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
75
90
|
coHost: {HINT_4: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
91
|
+
presenter: {HINT_5: true},
|
|
92
|
+
panelist: {HINT_6: true},
|
|
93
|
+
attendee: {HINT_7: true},
|
|
76
94
|
userDisplayHints: ['VOIP_IS_ENABLED', 'HINT_1', 'HINT_2', 'LOWER_SOMEONE_ELSES_HAND'],
|
|
77
95
|
});
|
|
78
96
|
|
|
@@ -80,6 +98,9 @@ describe('plugin-meetings', () => {
|
|
|
80
98
|
policy: {HINT_3: true, VOIP_IS_ENABLED: true},
|
|
81
99
|
moderator: {HINT_1: true, HINT_2: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
82
100
|
coHost: {HINT_4: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
101
|
+
presenter: {HINT_5: true},
|
|
102
|
+
panelist: {HINT_6: true},
|
|
103
|
+
attendee: {HINT_7: true},
|
|
83
104
|
userDisplayHints: [
|
|
84
105
|
'HINT_3',
|
|
85
106
|
'VOIP_IS_ENABLED',
|
|
@@ -90,10 +111,49 @@ describe('plugin-meetings', () => {
|
|
|
90
111
|
});
|
|
91
112
|
});
|
|
92
113
|
|
|
114
|
+
it('merges presenter hints when user has PRESENTER role', () => {
|
|
115
|
+
assert.deepEqual(InfoUtils.parse(info, ['PRESENTER']), {
|
|
116
|
+
policy: {HINT_3: true, VOIP_IS_ENABLED: true},
|
|
117
|
+
moderator: {HINT_1: true, HINT_2: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
118
|
+
coHost: {HINT_4: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
119
|
+
presenter: {HINT_5: true},
|
|
120
|
+
panelist: {HINT_6: true},
|
|
121
|
+
attendee: {HINT_7: true},
|
|
122
|
+
userDisplayHints: ['HINT_3', 'VOIP_IS_ENABLED', 'HINT_5'],
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('merges panelist hints when user has PANELIST role', () => {
|
|
127
|
+
assert.deepEqual(InfoUtils.parse(info, ['PANELIST']), {
|
|
128
|
+
policy: {HINT_3: true, VOIP_IS_ENABLED: true},
|
|
129
|
+
moderator: {HINT_1: true, HINT_2: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
130
|
+
coHost: {HINT_4: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
131
|
+
presenter: {HINT_5: true},
|
|
132
|
+
panelist: {HINT_6: true},
|
|
133
|
+
attendee: {HINT_7: true},
|
|
134
|
+
userDisplayHints: ['HINT_3', 'VOIP_IS_ENABLED', 'HINT_6'],
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('merges attendee hints when user has ATTENDEE role', () => {
|
|
139
|
+
assert.deepEqual(InfoUtils.parse(info, ['ATTENDEE']), {
|
|
140
|
+
policy: {HINT_3: true, VOIP_IS_ENABLED: true},
|
|
141
|
+
moderator: {HINT_1: true, HINT_2: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
142
|
+
coHost: {HINT_4: true, LOWER_SOMEONE_ELSES_HAND: true},
|
|
143
|
+
presenter: {HINT_5: true},
|
|
144
|
+
panelist: {HINT_6: true},
|
|
145
|
+
attendee: {HINT_7: true},
|
|
146
|
+
userDisplayHints: ['HINT_3', 'VOIP_IS_ENABLED', 'HINT_7'],
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
93
150
|
it('only adds datachannel url when present', () => {
|
|
94
151
|
assert.deepEqual(InfoUtils.parse({datachannelUrl: 'some url'}, []), {
|
|
95
152
|
coHost: {LOWER_SOMEONE_ELSES_HAND: true},
|
|
96
153
|
moderator: {LOWER_SOMEONE_ELSES_HAND: true},
|
|
154
|
+
presenter: {},
|
|
155
|
+
panelist: {},
|
|
156
|
+
attendee: {},
|
|
97
157
|
datachannelUrl: 'some url',
|
|
98
158
|
policy: {},
|
|
99
159
|
userDisplayHints: [],
|
|
@@ -102,6 +162,9 @@ describe('plugin-meetings', () => {
|
|
|
102
162
|
assert.deepEqual(InfoUtils.parse({}, []), {
|
|
103
163
|
coHost: {LOWER_SOMEONE_ELSES_HAND: true},
|
|
104
164
|
moderator: {LOWER_SOMEONE_ELSES_HAND: true},
|
|
165
|
+
presenter: {},
|
|
166
|
+
panelist: {},
|
|
167
|
+
attendee: {},
|
|
105
168
|
policy: {},
|
|
106
169
|
userDisplayHints: [],
|
|
107
170
|
});
|
|
@@ -171,6 +234,30 @@ describe('plugin-meetings', () => {
|
|
|
171
234
|
LOWER_SOMEONE_ELSES_HAND: true,
|
|
172
235
|
});
|
|
173
236
|
});
|
|
237
|
+
|
|
238
|
+
it('parsePresenter calls parseDisplayHintSection correctly and returns the result', () => {
|
|
239
|
+
const result = InfoUtils.parsePresenter(info);
|
|
240
|
+
|
|
241
|
+
assert.calledWith(parseDisplayHintSectionSpy, info, 'presenter');
|
|
242
|
+
|
|
243
|
+
assert.deepEqual(result, parseDisplayHintSectionSpy.firstCall.returnValue);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('parsePanelist calls parseDisplayHintSection correctly and returns the result', () => {
|
|
247
|
+
const result = InfoUtils.parsePanelist(info);
|
|
248
|
+
|
|
249
|
+
assert.calledWith(parseDisplayHintSectionSpy, info, 'panelist');
|
|
250
|
+
|
|
251
|
+
assert.deepEqual(result, parseDisplayHintSectionSpy.firstCall.returnValue);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('parseAttendee calls parseDisplayHintSection correctly and returns the result', () => {
|
|
255
|
+
const result = InfoUtils.parseAttendee(info);
|
|
256
|
+
|
|
257
|
+
assert.calledWith(parseDisplayHintSectionSpy, info, 'attendee');
|
|
258
|
+
|
|
259
|
+
assert.deepEqual(result, parseDisplayHintSectionSpy.firstCall.returnValue);
|
|
260
|
+
});
|
|
174
261
|
});
|
|
175
262
|
});
|
|
176
263
|
});
|
|
@@ -115,6 +115,7 @@ describe('plugin-meetings', () => {
|
|
|
115
115
|
canAttendeeRequestAiAssistantEnabled: null,
|
|
116
116
|
isAttendeeRequestAiAssistantDeclinedAll: null,
|
|
117
117
|
isAnonymizeDisplayNamesEnabled: null,
|
|
118
|
+
canViewTheParticipantList: null,
|
|
118
119
|
|
|
119
120
|
...expected,
|
|
120
121
|
};
|
|
@@ -236,6 +237,7 @@ describe('plugin-meetings', () => {
|
|
|
236
237
|
'canAttendeeRequestAiAssistantEnabled',
|
|
237
238
|
'isAttendeeRequestAiAssistantDeclinedAll',
|
|
238
239
|
'isAnonymizeDisplayNamesEnabled',
|
|
240
|
+
'canViewTheParticipantList',
|
|
239
241
|
].forEach((key) => {
|
|
240
242
|
it(`get and set for ${key} work as expected`, () => {
|
|
241
243
|
const inMeetingActions = new InMeetingActions();
|