@webex/plugin-meetings 3.12.0-next.6 → 3.12.0-next.60
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/AGENTS.md +9 -0
- package/dist/aiEnableRequest/index.js +15 -2
- package/dist/aiEnableRequest/index.js.map +1 -1
- package/dist/breakouts/breakout.js +8 -3
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/index.js +26 -2
- package/dist/breakouts/index.js.map +1 -1
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +6 -3
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.js +11 -1
- package/dist/controls-options-manager/constants.js.map +1 -1
- package/dist/controls-options-manager/index.js +38 -24
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/util.js +91 -0
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/hashTree/constants.js +10 -1
- package/dist/hashTree/constants.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +716 -370
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/utils.js +22 -0
- package/dist/hashTree/utils.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/interceptors/locusRetry.js +23 -8
- package/dist/interceptors/locusRetry.js.map +1 -1
- package/dist/interpretation/index.js +10 -1
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +4 -1
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +289 -87
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/types.js +19 -0
- package/dist/locus-info/types.js.map +1 -1
- package/dist/media/index.js +3 -1
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +1 -0
- package/dist/media/properties.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 +907 -535
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/util.js +19 -2
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +231 -78
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +6 -1
- package/dist/meetings/meetings.types.js.map +1 -1
- package/dist/meetings/request.js +39 -0
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +79 -5
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +10 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js.map +1 -1
- package/dist/member/util.js +3 -0
- package/dist/member/util.js.map +1 -1
- package/dist/metrics/constants.js +4 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/codec/constants.js +63 -0
- package/dist/multistream/codec/constants.js.map +1 -0
- package/dist/multistream/mediaRequestManager.js +62 -15
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +9 -0
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/recording-controller/index.js +1 -3
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/types/config.d.ts +2 -0
- package/dist/types/constants.d.ts +2 -0
- package/dist/types/controls-options-manager/constants.d.ts +6 -1
- package/dist/types/controls-options-manager/index.d.ts +10 -0
- package/dist/types/hashTree/constants.d.ts +1 -0
- package/dist/types/hashTree/hashTreeParser.d.ts +92 -16
- package/dist/types/hashTree/utils.d.ts +11 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/interceptors/locusRetry.d.ts +4 -4
- package/dist/types/locus-info/index.d.ts +46 -6
- package/dist/types/locus-info/types.d.ts +21 -1
- package/dist/types/media/properties.d.ts +1 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +2 -0
- package/dist/types/meeting/index.d.ts +87 -3
- package/dist/types/meeting/util.d.ts +8 -0
- package/dist/types/meetings/index.d.ts +30 -2
- package/dist/types/meetings/meetings.types.d.ts +15 -0
- package/dist/types/meetings/request.d.ts +14 -0
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/member/types.d.ts +1 -0
- package/dist/types/member/util.d.ts +1 -0
- package/dist/types/metrics/constants.d.ts +3 -0
- package/dist/types/multistream/codec/constants.d.ts +7 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +22 -5
- package/dist/types/reactions/reactions.type.d.ts +3 -0
- package/dist/webinar/index.js +361 -235
- package/dist/webinar/index.js.map +1 -1
- package/package.json +22 -22
- package/src/aiEnableRequest/index.ts +16 -0
- package/src/breakouts/breakout.ts +3 -1
- package/src/breakouts/index.ts +31 -0
- package/src/config.ts +2 -0
- package/src/constants.ts +5 -1
- package/src/controls-options-manager/constants.ts +14 -1
- package/src/controls-options-manager/index.ts +47 -24
- package/src/controls-options-manager/util.ts +81 -1
- package/src/hashTree/constants.ts +9 -0
- package/src/hashTree/hashTreeParser.ts +429 -183
- package/src/hashTree/utils.ts +17 -0
- package/src/index.ts +5 -0
- package/src/interceptors/locusRetry.ts +25 -4
- package/src/interpretation/index.ts +25 -8
- package/src/locus-info/controlsUtils.ts +3 -1
- package/src/locus-info/index.ts +291 -97
- package/src/locus-info/types.ts +25 -1
- package/src/media/index.ts +3 -0
- package/src/media/properties.ts +1 -0
- package/src/meeting/in-meeting-actions.ts +4 -0
- package/src/meeting/index.ts +388 -33
- package/src/meeting/util.ts +20 -2
- package/src/meetings/index.ts +134 -44
- package/src/meetings/meetings.types.ts +19 -0
- package/src/meetings/request.ts +43 -0
- package/src/meetings/util.ts +97 -1
- package/src/member/index.ts +10 -0
- package/src/member/types.ts +1 -0
- package/src/member/util.ts +3 -0
- package/src/metrics/constants.ts +3 -0
- package/src/multistream/codec/constants.ts +58 -0
- package/src/multistream/mediaRequestManager.ts +119 -28
- package/src/multistream/receiveSlot.ts +18 -0
- package/src/reactions/reactions.type.ts +3 -0
- package/src/recording-controller/index.ts +1 -2
- package/src/webinar/index.ts +162 -21
- package/test/unit/spec/aiEnableRequest/index.ts +86 -0
- package/test/unit/spec/breakouts/breakout.ts +9 -3
- package/test/unit/spec/breakouts/index.ts +49 -0
- package/test/unit/spec/controls-options-manager/index.js +140 -29
- package/test/unit/spec/controls-options-manager/util.js +165 -0
- package/test/unit/spec/hashTree/hashTreeParser.ts +1508 -149
- package/test/unit/spec/hashTree/utils.ts +88 -1
- package/test/unit/spec/interceptors/locusRetry.ts +205 -4
- package/test/unit/spec/interpretation/index.ts +26 -4
- package/test/unit/spec/locus-info/controlsUtils.js +172 -57
- package/test/unit/spec/locus-info/index.js +475 -81
- package/test/unit/spec/media/index.ts +31 -0
- package/test/unit/spec/meeting/in-meeting-actions.ts +2 -0
- package/test/unit/spec/meeting/index.js +1131 -49
- package/test/unit/spec/meeting/muteState.js +3 -0
- package/test/unit/spec/meeting/utils.js +33 -0
- package/test/unit/spec/meetings/index.js +360 -10
- package/test/unit/spec/meetings/request.js +141 -0
- package/test/unit/spec/meetings/utils.js +189 -0
- package/test/unit/spec/member/index.js +7 -0
- package/test/unit/spec/member/util.js +24 -0
- package/test/unit/spec/multistream/mediaRequestManager.ts +501 -37
- package/test/unit/spec/recording-controller/index.js +9 -8
- package/test/unit/spec/webinar/index.ts +141 -16
|
@@ -55,6 +55,27 @@ describe('plugin-meetings', () => {
|
|
|
55
55
|
});
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
+
describe('#locusUrlUpdate', () => {
|
|
59
|
+
it('should update the locusUrl property', () => {
|
|
60
|
+
const testLocusUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/test-id';
|
|
61
|
+
|
|
62
|
+
aiEnableRequest.locusUrlUpdate(testLocusUrl);
|
|
63
|
+
|
|
64
|
+
assert.equal(aiEnableRequest.locusUrl, testLocusUrl);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should handle updating locusUrl multiple times', () => {
|
|
68
|
+
const firstUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/test-id-1';
|
|
69
|
+
const secondUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/test-id-2';
|
|
70
|
+
|
|
71
|
+
aiEnableRequest.locusUrlUpdate(firstUrl);
|
|
72
|
+
assert.equal(aiEnableRequest.locusUrl, firstUrl);
|
|
73
|
+
|
|
74
|
+
aiEnableRequest.locusUrlUpdate(secondUrl);
|
|
75
|
+
assert.equal(aiEnableRequest.locusUrl, secondUrl);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
58
79
|
describe('#selfParticipantIdUpdate', () => {
|
|
59
80
|
it('should update the selfParticipantId property', () => {
|
|
60
81
|
const testSelfParticipantId = 'participant-123';
|
|
@@ -254,6 +275,71 @@ describe('plugin-meetings', () => {
|
|
|
254
275
|
sinon.assert.notCalled(triggerSpy);
|
|
255
276
|
});
|
|
256
277
|
|
|
278
|
+
it('should not trigger event when locusUrl does not match', () => {
|
|
279
|
+
const testLocusUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/test-id';
|
|
280
|
+
const differentLocusUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/different-id';
|
|
281
|
+
|
|
282
|
+
aiEnableRequest.locusUrl = testLocusUrl;
|
|
283
|
+
|
|
284
|
+
// Reset the spy after setting locusUrl to avoid counting property change events
|
|
285
|
+
triggerSpy.resetHistory();
|
|
286
|
+
|
|
287
|
+
aiEnableRequest.listenToApprovalRequests();
|
|
288
|
+
|
|
289
|
+
const event = {
|
|
290
|
+
data: {
|
|
291
|
+
locusUrl: differentLocusUrl,
|
|
292
|
+
approval: {
|
|
293
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
294
|
+
receivers: [{participantId: testSelfParticipantId}],
|
|
295
|
+
initiator: {participantId: testInitiatorId},
|
|
296
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
297
|
+
url: testUrl,
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
webex.internal.mercury.emit(`event:${LOCUSEVENT.APPROVAL_REQUEST}`, event);
|
|
303
|
+
|
|
304
|
+
sinon.assert.notCalled(triggerSpy);
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it('should trigger event when locusUrl matches', () => {
|
|
308
|
+
const testLocusUrl = 'https://locus-a.wbx2.com/locus/api/v1/loci/test-id';
|
|
309
|
+
|
|
310
|
+
aiEnableRequest.locusUrl = testLocusUrl;
|
|
311
|
+
|
|
312
|
+
// Reset the spy after setting locusUrl to avoid counting property change events
|
|
313
|
+
triggerSpy.resetHistory();
|
|
314
|
+
|
|
315
|
+
aiEnableRequest.listenToApprovalRequests();
|
|
316
|
+
|
|
317
|
+
const event = {
|
|
318
|
+
data: {
|
|
319
|
+
locusUrl: testLocusUrl,
|
|
320
|
+
approval: {
|
|
321
|
+
resourceType: AI_ENABLE_REQUEST.RESOURCE_TYPE,
|
|
322
|
+
receivers: [{participantId: testSelfParticipantId}],
|
|
323
|
+
initiator: {participantId: testInitiatorId},
|
|
324
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
325
|
+
url: testUrl,
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
webex.internal.mercury.emit(`event:${LOCUSEVENT.APPROVAL_REQUEST}`, event);
|
|
331
|
+
|
|
332
|
+
sinon.assert.calledOnce(triggerSpy);
|
|
333
|
+
sinon.assert.calledWith(triggerSpy, AI_ENABLE_REQUEST.EVENTS.APPROVAL_REQUEST_ARRIVED, {
|
|
334
|
+
actionType: AI_ENABLE_REQUEST.ACTION_TYPE.REQUESTED,
|
|
335
|
+
isApprover: true,
|
|
336
|
+
isInitiator: false,
|
|
337
|
+
initiatorId: testInitiatorId,
|
|
338
|
+
approverId: testSelfParticipantId,
|
|
339
|
+
url: testUrl,
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
|
|
257
343
|
it('should handle events with different action types', () => {
|
|
258
344
|
aiEnableRequest.listenToApprovalRequests();
|
|
259
345
|
|
|
@@ -26,6 +26,7 @@ describe('plugin-meetings', () => {
|
|
|
26
26
|
breakout.sessionId = 'sessionId';
|
|
27
27
|
breakout.sessionType = 'BREAKOUT';
|
|
28
28
|
breakout.url = 'url';
|
|
29
|
+
breakout.resourceLink = 'resource-link';
|
|
29
30
|
breakout.collection = {
|
|
30
31
|
parent: {
|
|
31
32
|
meetingId: 'activeMeetingId',
|
|
@@ -45,6 +46,7 @@ describe('plugin-meetings', () => {
|
|
|
45
46
|
describe('initialize', () => {
|
|
46
47
|
it('creates the object correctly', () => {
|
|
47
48
|
assert.instanceOf(breakout.breakoutRequest, BreakoutRequest);
|
|
49
|
+
assert.equal(breakout.resourceLink, 'resource-link');
|
|
48
50
|
});
|
|
49
51
|
});
|
|
50
52
|
|
|
@@ -217,10 +219,14 @@ describe('plugin-meetings', () => {
|
|
|
217
219
|
locusParticipantsUpdate: sinon.stub(),
|
|
218
220
|
};
|
|
219
221
|
|
|
220
|
-
const locusData = {
|
|
222
|
+
const locusData = {participants: [{id: 'participant-1'}], sequence: {entries: [123]}};
|
|
221
223
|
const result = breakout.parseRoster(locusData);
|
|
222
224
|
|
|
223
|
-
assert.calledOnceWithExactly(breakout.members.locusParticipantsUpdate,
|
|
225
|
+
assert.calledOnceWithExactly(breakout.members.locusParticipantsUpdate, {
|
|
226
|
+
participants: [{id: 'participant-1'}],
|
|
227
|
+
isReplace: true,
|
|
228
|
+
});
|
|
229
|
+
assert.equal(breakout.breakoutRosterLocus, locusData);
|
|
224
230
|
assert.equal(result, undefined);
|
|
225
231
|
});
|
|
226
232
|
it('not call locusParticipantsUpdate if sequence is expired', () => {
|
|
@@ -228,7 +234,7 @@ describe('plugin-meetings', () => {
|
|
|
228
234
|
locusParticipantsUpdate: sinon.stub(),
|
|
229
235
|
};
|
|
230
236
|
breakout.isNeedHandleRoster = sinon.stub().returns(false);
|
|
231
|
-
const locusData = {
|
|
237
|
+
const locusData = {participants: [{id: 'participant-1'}], sequence: {entries: [123]}};
|
|
232
238
|
breakout.parseRoster(locusData);
|
|
233
239
|
|
|
234
240
|
assert.notCalled(breakout.members.locusParticipantsUpdate);
|
|
@@ -313,6 +313,7 @@ describe('plugin-meetings', () => {
|
|
|
313
313
|
groupId: 'groupId',
|
|
314
314
|
sessionType: 'sessionType',
|
|
315
315
|
url: 'url',
|
|
316
|
+
resourceLink: 'resource-link',
|
|
316
317
|
name: 'name',
|
|
317
318
|
allowBackToMain: true,
|
|
318
319
|
delayCloseTime: 10,
|
|
@@ -339,6 +340,7 @@ describe('plugin-meetings', () => {
|
|
|
339
340
|
assert.equal(breakouts.currentBreakoutSession.current, true);
|
|
340
341
|
assert.equal(breakouts.currentBreakoutSession.sessionType, 'sessionType');
|
|
341
342
|
assert.equal(breakouts.currentBreakoutSession.url, 'url');
|
|
343
|
+
assert.equal(breakouts.currentBreakoutSession.resourceLink, 'resource-link');
|
|
342
344
|
assert.equal(breakouts.currentBreakoutSession.active, false);
|
|
343
345
|
assert.equal(breakouts.currentBreakoutSession.allowed, false);
|
|
344
346
|
assert.equal(breakouts.currentBreakoutSession.assigned, false);
|
|
@@ -1847,6 +1849,53 @@ describe('plugin-meetings', () => {
|
|
|
1847
1849
|
});
|
|
1848
1850
|
});
|
|
1849
1851
|
|
|
1852
|
+
describe('#removeFromBreakout', () => {
|
|
1853
|
+
it('should make a POST request with correct body and return the result', async () => {
|
|
1854
|
+
breakouts.request = sinon.stub().returns(Promise.resolve('REQUEST_RETURN_VALUE'));
|
|
1855
|
+
breakouts.set('url', 'url');
|
|
1856
|
+
breakouts.set('mainGroupId', 'mainGroupId');
|
|
1857
|
+
breakouts.set('mainSessionId', 'mainSessionId');
|
|
1858
|
+
|
|
1859
|
+
const participants = ['participant1', 'participant2'];
|
|
1860
|
+
const result = await breakouts.removeFromBreakout(participants);
|
|
1861
|
+
|
|
1862
|
+
assert.calledOnceWithExactly(breakouts.request, {
|
|
1863
|
+
method: 'POST',
|
|
1864
|
+
uri: 'url/move',
|
|
1865
|
+
body: {
|
|
1866
|
+
groups: [
|
|
1867
|
+
{
|
|
1868
|
+
id: 'mainGroupId',
|
|
1869
|
+
sessions: [
|
|
1870
|
+
{
|
|
1871
|
+
id: 'mainSessionId',
|
|
1872
|
+
participants,
|
|
1873
|
+
},
|
|
1874
|
+
],
|
|
1875
|
+
},
|
|
1876
|
+
],
|
|
1877
|
+
},
|
|
1878
|
+
});
|
|
1879
|
+
assert.equal(result, 'REQUEST_RETURN_VALUE');
|
|
1880
|
+
});
|
|
1881
|
+
|
|
1882
|
+
it('should throw an error if mainGroupId is missing', () => {
|
|
1883
|
+
breakouts.set('mainSessionId', 'mainSessionId');
|
|
1884
|
+
assert.throws(
|
|
1885
|
+
() => breakouts.removeFromBreakout(['participant1']),
|
|
1886
|
+
'Main group ID and session ID must be available to remove participants from breakout'
|
|
1887
|
+
);
|
|
1888
|
+
});
|
|
1889
|
+
|
|
1890
|
+
it('should throw an error if mainSessionId is missing', () => {
|
|
1891
|
+
breakouts.set('mainGroupId', 'mainGroupId');
|
|
1892
|
+
assert.throws(
|
|
1893
|
+
() => breakouts.removeFromBreakout(['participant1']),
|
|
1894
|
+
'Main group ID and session ID must be available to remove participants from breakout'
|
|
1895
|
+
);
|
|
1896
|
+
});
|
|
1897
|
+
});
|
|
1898
|
+
|
|
1850
1899
|
describe('#triggerReturnToMainEvent', () => {
|
|
1851
1900
|
const checkTrigger = ({breakout, shouldTrigger}) => {
|
|
1852
1901
|
breakouts.trigger = sinon.stub();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import ControlsOptionsManager from '@webex/plugin-meetings/src/controls-options-manager';
|
|
2
2
|
import Util from '@webex/plugin-meetings/src/controls-options-manager/util';
|
|
3
|
+
import ParameterError from '@webex/plugin-meetings/src/common/errors/parameter';
|
|
3
4
|
import sinon from 'sinon';
|
|
4
5
|
import {assert} from '@webex/test-helper-chai';
|
|
5
6
|
import { HTTP_VERBS } from '@webex/plugin-meetings/src/constants';
|
|
@@ -26,6 +27,7 @@ describe('plugin-meetings', () => {
|
|
|
26
27
|
beforeEach(() => {
|
|
27
28
|
request = {
|
|
28
29
|
request: sinon.stub().returns(Promise.resolve()),
|
|
30
|
+
locusDeltaRequest: sinon.stub().returns(Promise.resolve()),
|
|
29
31
|
};
|
|
30
32
|
|
|
31
33
|
manager = new ControlsOptionsManager(request);
|
|
@@ -58,11 +60,11 @@ describe('plugin-meetings', () => {
|
|
|
58
60
|
|
|
59
61
|
const result = manager.setMuteOnEntry(true);
|
|
60
62
|
|
|
61
|
-
assert.calledWith(request.
|
|
63
|
+
assert.calledWith(request.locusDeltaRequest, { uri: 'test/id/controls',
|
|
62
64
|
body: { muteOnEntry: { enabled: true } },
|
|
63
65
|
method: HTTP_VERBS.PATCH});
|
|
64
66
|
|
|
65
|
-
assert.deepEqual(result, request.
|
|
67
|
+
assert.deepEqual(result, request.locusDeltaRequest.firstCall.returnValue);
|
|
66
68
|
});
|
|
67
69
|
|
|
68
70
|
it('can set mute on entry when the display hint is available enabled=false', () => {
|
|
@@ -70,11 +72,24 @@ describe('plugin-meetings', () => {
|
|
|
70
72
|
|
|
71
73
|
const result = manager.setMuteOnEntry(false);
|
|
72
74
|
|
|
73
|
-
assert.calledWith(request.
|
|
75
|
+
assert.calledWith(request.locusDeltaRequest, { uri: 'test/id/controls',
|
|
74
76
|
body: { muteOnEntry: { enabled: false } },
|
|
75
77
|
method: HTTP_VERBS.PATCH});
|
|
76
78
|
|
|
77
|
-
assert.deepEqual(result, request.
|
|
79
|
+
assert.deepEqual(result, request.locusDeltaRequest.firstCall.returnValue);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should send setMuteOnEntry to locusUrl without authorizingLocusUrl when in breakout', () => {
|
|
83
|
+
manager.setDisplayHints(['ENABLE_MUTE_ON_ENTRY']);
|
|
84
|
+
manager.mainLocusUrl = 'test/main';
|
|
85
|
+
|
|
86
|
+
const result = manager.setMuteOnEntry(true);
|
|
87
|
+
|
|
88
|
+
assert.calledWith(request.locusDeltaRequest, { uri: 'test/id/controls',
|
|
89
|
+
body: { muteOnEntry: { enabled: true } },
|
|
90
|
+
method: HTTP_VERBS.PATCH});
|
|
91
|
+
|
|
92
|
+
assert.deepEqual(result, request.locusDeltaRequest.firstCall.returnValue);
|
|
78
93
|
});
|
|
79
94
|
});
|
|
80
95
|
|
|
@@ -100,11 +115,11 @@ describe('plugin-meetings', () => {
|
|
|
100
115
|
|
|
101
116
|
const result = manager.setDisallowUnmute(true);
|
|
102
117
|
|
|
103
|
-
assert.calledWith(request.
|
|
118
|
+
assert.calledWith(request.locusDeltaRequest, { uri: 'test/id/controls',
|
|
104
119
|
body: { disallowUnmute: { enabled: true } },
|
|
105
120
|
method: HTTP_VERBS.PATCH});
|
|
106
121
|
|
|
107
|
-
assert.deepEqual(result, request.
|
|
122
|
+
assert.deepEqual(result, request.locusDeltaRequest.firstCall.returnValue);
|
|
108
123
|
});
|
|
109
124
|
|
|
110
125
|
it('can set allow unmute when DISABLE_HARD_MUTE display hint is available', () => {
|
|
@@ -112,11 +127,24 @@ describe('plugin-meetings', () => {
|
|
|
112
127
|
|
|
113
128
|
const result = manager.setDisallowUnmute(false);
|
|
114
129
|
|
|
115
|
-
assert.calledWith(request.
|
|
130
|
+
assert.calledWith(request.locusDeltaRequest, { uri: 'test/id/controls',
|
|
116
131
|
body: { disallowUnmute: { enabled: false } },
|
|
117
132
|
method: HTTP_VERBS.PATCH});
|
|
118
133
|
|
|
119
|
-
assert.deepEqual(result, request.
|
|
134
|
+
assert.deepEqual(result, request.locusDeltaRequest.firstCall.returnValue);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('should send setDisallowUnmute to locusUrl without authorizingLocusUrl when in breakout', () => {
|
|
138
|
+
manager.setDisplayHints(['ENABLE_HARD_MUTE']);
|
|
139
|
+
manager.mainLocusUrl = 'test/main';
|
|
140
|
+
|
|
141
|
+
const result = manager.setDisallowUnmute(true);
|
|
142
|
+
|
|
143
|
+
assert.calledWith(request.locusDeltaRequest, { uri: 'test/id/controls',
|
|
144
|
+
body: { disallowUnmute: { enabled: true } },
|
|
145
|
+
method: HTTP_VERBS.PATCH});
|
|
146
|
+
|
|
147
|
+
assert.deepEqual(result, request.locusDeltaRequest.firstCall.returnValue);
|
|
120
148
|
});
|
|
121
149
|
});
|
|
122
150
|
});
|
|
@@ -127,6 +155,7 @@ describe('plugin-meetings', () => {
|
|
|
127
155
|
beforeEach(() => {
|
|
128
156
|
request = {
|
|
129
157
|
request: sinon.stub().resolves(),
|
|
158
|
+
locusDeltaRequest: sinon.stub().resolves(),
|
|
130
159
|
};
|
|
131
160
|
|
|
132
161
|
manager = new ControlsOptionsManager(request);
|
|
@@ -138,6 +167,18 @@ describe('plugin-meetings', () => {
|
|
|
138
167
|
});
|
|
139
168
|
});
|
|
140
169
|
|
|
170
|
+
it('should reject with ParameterError when locusUrl is not set', () => {
|
|
171
|
+
const noLocusManager = new ControlsOptionsManager(request);
|
|
172
|
+
|
|
173
|
+
const result = noLocusManager.update({scope: 'audio', properties: {muted: true}});
|
|
174
|
+
|
|
175
|
+
assert.notCalled(request.request);
|
|
176
|
+
return assert.isRejected(result).then((err) => {
|
|
177
|
+
assert.instanceOf(err, ParameterError);
|
|
178
|
+
assert.match(err.message, /locusUrl.*must be defined/);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
141
182
|
it('should throw an error if the scope is not supported', () => {
|
|
142
183
|
const scope = 'invalid';
|
|
143
184
|
|
|
@@ -163,7 +204,7 @@ describe('plugin-meetings', () => {
|
|
|
163
204
|
|
|
164
205
|
return manager.update(audio, reactions)
|
|
165
206
|
.then(() => {
|
|
166
|
-
assert.calledWith(request.
|
|
207
|
+
assert.calledWith(request.locusDeltaRequest, {
|
|
167
208
|
uri: 'test/id/controls',
|
|
168
209
|
body: {
|
|
169
210
|
audio: audio.properties,
|
|
@@ -171,7 +212,7 @@ describe('plugin-meetings', () => {
|
|
|
171
212
|
method: HTTP_VERBS.PATCH,
|
|
172
213
|
});
|
|
173
214
|
|
|
174
|
-
assert.calledWith(request.
|
|
215
|
+
assert.calledWith(request.locusDeltaRequest, {
|
|
175
216
|
uri: 'test/id/controls',
|
|
176
217
|
body: {
|
|
177
218
|
reactions: reactions.properties,
|
|
@@ -203,7 +244,7 @@ describe('plugin-meetings', () => {
|
|
|
203
244
|
});
|
|
204
245
|
});
|
|
205
246
|
|
|
206
|
-
it('should
|
|
247
|
+
it('should send audio controls to locusUrl without authorizingLocusUrl and non-audio to mainLocusUrl with authorizingLocusUrl when in breakout', () => {
|
|
207
248
|
const restorable = Util.canUpdate;
|
|
208
249
|
Util.canUpdate = sinon.stub().returns(true);
|
|
209
250
|
manager.mainLocusUrl = 'test/main';
|
|
@@ -213,20 +254,64 @@ describe('plugin-meetings', () => {
|
|
|
213
254
|
|
|
214
255
|
return manager.update(audio, reactions)
|
|
215
256
|
.then(() => {
|
|
257
|
+
// Audio controls go directly to current locusUrl (no cross-locus authorization)
|
|
258
|
+
assert.calledWith(request.locusDeltaRequest, {
|
|
259
|
+
uri: 'test/id/controls',
|
|
260
|
+
body: {
|
|
261
|
+
audio: audio.properties,
|
|
262
|
+
},
|
|
263
|
+
method: HTTP_VERBS.PATCH,
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
// Non-audio controls go to mainLocusUrl with authorizingLocusUrl
|
|
216
267
|
assert.calledWith(request.request, {
|
|
217
268
|
uri: 'test/main/controls',
|
|
218
269
|
body: {
|
|
219
|
-
|
|
270
|
+
reactions: reactions.properties,
|
|
220
271
|
authorizingLocusUrl: 'test/id'
|
|
221
272
|
},
|
|
222
273
|
method: HTTP_VERBS.PATCH,
|
|
223
274
|
});
|
|
224
275
|
|
|
276
|
+
Util.canUpdate = restorable;
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it('should send audio controls to locusUrl without authorizingLocusUrl when in breakout', () => {
|
|
281
|
+
const restorable = Util.canUpdate;
|
|
282
|
+
Util.canUpdate = sinon.stub().returns(true);
|
|
283
|
+
manager.mainLocusUrl = 'test/main';
|
|
284
|
+
|
|
285
|
+
const audio = {scope: 'audio', properties: {muted: true, disallowUnmute: false}};
|
|
286
|
+
|
|
287
|
+
return manager.update(audio)
|
|
288
|
+
.then(() => {
|
|
289
|
+
assert.calledWith(request.locusDeltaRequest, {
|
|
290
|
+
uri: 'test/id/controls',
|
|
291
|
+
body: {
|
|
292
|
+
audio: audio.properties,
|
|
293
|
+
},
|
|
294
|
+
method: HTTP_VERBS.PATCH,
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
Util.canUpdate = restorable;
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
it('should send non-audio controls to mainLocusUrl with authorizingLocusUrl when in breakout', () => {
|
|
302
|
+
const restorable = Util.canUpdate;
|
|
303
|
+
Util.canUpdate = sinon.stub().returns(true);
|
|
304
|
+
manager.mainLocusUrl = 'test/main';
|
|
305
|
+
|
|
306
|
+
const reactions = {scope: 'reactions', properties: {enabled: true}};
|
|
307
|
+
|
|
308
|
+
return manager.update(reactions)
|
|
309
|
+
.then(() => {
|
|
225
310
|
assert.calledWith(request.request, {
|
|
226
311
|
uri: 'test/main/controls',
|
|
227
312
|
body: {
|
|
228
313
|
reactions: reactions.properties,
|
|
229
|
-
authorizingLocusUrl: 'test/id'
|
|
314
|
+
authorizingLocusUrl: 'test/id',
|
|
230
315
|
},
|
|
231
316
|
method: HTTP_VERBS.PATCH,
|
|
232
317
|
});
|
|
@@ -241,6 +326,7 @@ describe('plugin-meetings', () => {
|
|
|
241
326
|
beforeEach(() => {
|
|
242
327
|
request = {
|
|
243
328
|
request: sinon.stub().returns(Promise.resolve()),
|
|
329
|
+
locusDeltaRequest: sinon.stub().returns(Promise.resolve()),
|
|
244
330
|
};
|
|
245
331
|
|
|
246
332
|
manager = new ControlsOptionsManager(request);
|
|
@@ -252,6 +338,18 @@ describe('plugin-meetings', () => {
|
|
|
252
338
|
})
|
|
253
339
|
});
|
|
254
340
|
|
|
341
|
+
it('should reject with ParameterError when locusUrl is not set', () => {
|
|
342
|
+
const noLocusManager = new ControlsOptionsManager(request);
|
|
343
|
+
|
|
344
|
+
const result = noLocusManager.setMuteAll(true, true, true);
|
|
345
|
+
|
|
346
|
+
assert.notCalled(request.request);
|
|
347
|
+
return assert.isRejected(result).then((err) => {
|
|
348
|
+
assert.instanceOf(err, ParameterError);
|
|
349
|
+
assert.match(err.message, /locusUrl.*must be defined/);
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
|
|
255
353
|
it('rejects when correct display hint is not present mutedEnabled=false', () => {
|
|
256
354
|
const result = manager.setMuteAll(false, false, false);
|
|
257
355
|
|
|
@@ -273,11 +371,11 @@ describe('plugin-meetings', () => {
|
|
|
273
371
|
|
|
274
372
|
const result = manager.setMuteAll(true, true, true);
|
|
275
373
|
|
|
276
|
-
assert.calledWith(request.
|
|
374
|
+
assert.calledWith(request.locusDeltaRequest, { uri: 'test/id/controls',
|
|
277
375
|
body: { audio: { muted: true, disallowUnmute: true, muteOnEntry: true } },
|
|
278
376
|
method: HTTP_VERBS.PATCH});
|
|
279
377
|
|
|
280
|
-
assert.deepEqual(result, request.
|
|
378
|
+
assert.deepEqual(result, request.locusDeltaRequest.firstCall.returnValue);
|
|
281
379
|
});
|
|
282
380
|
|
|
283
381
|
it('can set mute all when the display hint is available mutedEnabled=true', () => {
|
|
@@ -285,11 +383,11 @@ describe('plugin-meetings', () => {
|
|
|
285
383
|
|
|
286
384
|
const result = manager.setMuteAll(true, true, true);
|
|
287
385
|
|
|
288
|
-
assert.calledWith(request.
|
|
386
|
+
assert.calledWith(request.locusDeltaRequest, { uri: 'test/id/controls',
|
|
289
387
|
body: { audio: { muted: true, disallowUnmute: true, muteOnEntry: true } },
|
|
290
388
|
method: HTTP_VERBS.PATCH});
|
|
291
389
|
|
|
292
|
-
assert.deepEqual(result, request.
|
|
390
|
+
assert.deepEqual(result, request.locusDeltaRequest.firstCall.returnValue);
|
|
293
391
|
});
|
|
294
392
|
|
|
295
393
|
it('can set mute all when the display hint is available mutedEnabled=true', () => {
|
|
@@ -297,11 +395,11 @@ describe('plugin-meetings', () => {
|
|
|
297
395
|
|
|
298
396
|
const result = manager.setMuteAll(true, true, true);
|
|
299
397
|
|
|
300
|
-
assert.calledWith(request.
|
|
398
|
+
assert.calledWith(request.locusDeltaRequest, { uri: 'test/id/controls',
|
|
301
399
|
body: { audio: { muted: true, disallowUnmute: true, muteOnEntry: true } },
|
|
302
400
|
method: HTTP_VERBS.PATCH});
|
|
303
401
|
|
|
304
|
-
assert.deepEqual(result, request.
|
|
402
|
+
assert.deepEqual(result, request.locusDeltaRequest.firstCall.returnValue);
|
|
305
403
|
});
|
|
306
404
|
|
|
307
405
|
it('can set mute all when the display hint is available mutedEnabled=false', () => {
|
|
@@ -309,11 +407,11 @@ describe('plugin-meetings', () => {
|
|
|
309
407
|
|
|
310
408
|
const result = manager.setMuteAll(false, false, false);
|
|
311
409
|
|
|
312
|
-
assert.calledWith(request.
|
|
410
|
+
assert.calledWith(request.locusDeltaRequest, { uri: 'test/id/controls',
|
|
313
411
|
body: { audio: { muted: false, disallowUnmute: false, muteOnEntry: false } },
|
|
314
412
|
method: HTTP_VERBS.PATCH});
|
|
315
413
|
|
|
316
|
-
assert.deepEqual(result, request.
|
|
414
|
+
assert.deepEqual(result, request.locusDeltaRequest.firstCall.returnValue);
|
|
317
415
|
});
|
|
318
416
|
|
|
319
417
|
it('can set mute all panelists when the display hint is available mutedEnabled=true', () => {
|
|
@@ -321,11 +419,11 @@ describe('plugin-meetings', () => {
|
|
|
321
419
|
|
|
322
420
|
const result = manager.setMuteAll(true, true, true, ['panelist']);
|
|
323
421
|
|
|
324
|
-
assert.calledWith(request.
|
|
422
|
+
assert.calledWith(request.locusDeltaRequest, { uri: 'test/id/controls',
|
|
325
423
|
body: { audio: { muted: true, disallowUnmute: true, muteOnEntry: true, roles: ['panelist'] } },
|
|
326
424
|
method: HTTP_VERBS.PATCH});
|
|
327
425
|
|
|
328
|
-
assert.deepEqual(result, request.
|
|
426
|
+
assert.deepEqual(result, request.locusDeltaRequest.firstCall.returnValue);
|
|
329
427
|
});
|
|
330
428
|
|
|
331
429
|
it('can set mute all attendees when the display hint is available mutedEnabled=true', () => {
|
|
@@ -333,24 +431,37 @@ describe('plugin-meetings', () => {
|
|
|
333
431
|
|
|
334
432
|
const result = manager.setMuteAll(true, true, true, ['attendee']);
|
|
335
433
|
|
|
336
|
-
assert.calledWith(request.
|
|
434
|
+
assert.calledWith(request.locusDeltaRequest, { uri: 'test/id/controls',
|
|
337
435
|
body: { audio: { muted: true, disallowUnmute: true, muteOnEntry: true, roles: ['attendee'] } },
|
|
338
436
|
method: HTTP_VERBS.PATCH});
|
|
339
437
|
|
|
340
|
-
assert.deepEqual(result, request.
|
|
438
|
+
assert.deepEqual(result, request.locusDeltaRequest.firstCall.returnValue);
|
|
341
439
|
});
|
|
342
440
|
|
|
343
|
-
it('
|
|
441
|
+
it('should send setMuteAll to locusUrl without authorizingLocusUrl when in breakout', () => {
|
|
344
442
|
manager.setDisplayHints(['MUTE_ALL', 'DISABLE_HARD_MUTE', 'DISABLE_MUTE_ON_ENTRY']);
|
|
345
443
|
manager.mainLocusUrl = `test/main`;
|
|
346
444
|
|
|
347
445
|
const result = manager.setMuteAll(true, true, true, ['attendee']);
|
|
348
446
|
|
|
349
|
-
assert.calledWith(request.
|
|
350
|
-
body: { audio: { muted: true, disallowUnmute: true, muteOnEntry: true, roles: ['attendee'] }
|
|
447
|
+
assert.calledWith(request.locusDeltaRequest, { uri: 'test/id/controls',
|
|
448
|
+
body: { audio: { muted: true, disallowUnmute: true, muteOnEntry: true, roles: ['attendee'] } },
|
|
449
|
+
method: HTTP_VERBS.PATCH});
|
|
450
|
+
|
|
451
|
+
assert.deepEqual(result, request.locusDeltaRequest.firstCall.returnValue);
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
it('should send setMuteAll with PANELIST role to locusUrl without authorizingLocusUrl when in breakout', () => {
|
|
455
|
+
manager.setDisplayHints(['MUTE_ALL', 'ENABLE_HARD_MUTE', 'ENABLE_MUTE_ON_ENTRY']);
|
|
456
|
+
manager.mainLocusUrl = `test/main`;
|
|
457
|
+
|
|
458
|
+
const result = manager.setMuteAll(true, true, true, ['PANELIST']);
|
|
459
|
+
|
|
460
|
+
assert.calledWith(request.locusDeltaRequest, { uri: 'test/id/controls',
|
|
461
|
+
body: { audio: { muted: true, disallowUnmute: true, muteOnEntry: true, roles: ['PANELIST'] } },
|
|
351
462
|
method: HTTP_VERBS.PATCH});
|
|
352
463
|
|
|
353
|
-
assert.deepEqual(result, request.
|
|
464
|
+
assert.deepEqual(result, request.locusDeltaRequest.firstCall.returnValue);
|
|
354
465
|
});
|
|
355
466
|
});
|
|
356
467
|
});
|