@webex/plugin-meetings 3.9.0-multi-llms.4 → 3.9.0-multi-llms.5
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/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/constants.js +4 -0
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/index.js +22 -5
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js +7 -0
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interceptors/locusRouteToken.js +116 -0
- package/dist/interceptors/locusRouteToken.js.map +1 -0
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +11 -2
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +17 -3
- package/dist/locus-info/index.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +2 -0
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +74 -32
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +48 -14
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +3 -0
- package/dist/meeting/util.js.map +1 -1
- package/dist/member/index.js +9 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +10 -0
- package/dist/member/util.js.map +1 -1
- package/dist/types/constants.d.ts +3 -0
- package/dist/types/controls-options-manager/index.d.ts +9 -1
- package/dist/types/interceptors/index.d.ts +2 -1
- package/dist/types/interceptors/locusRouteToken.d.ts +38 -0
- package/dist/types/locus-info/index.d.ts +2 -1
- package/dist/types/meeting/in-meeting-actions.d.ts +2 -0
- package/dist/types/meeting/index.d.ts +14 -0
- package/dist/types/meeting/request.d.ts +16 -0
- package/dist/types/meeting/util.d.ts +1 -0
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/member/util.d.ts +5 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +13 -13
- package/src/constants.ts +6 -0
- package/src/controls-options-manager/index.ts +26 -5
- package/src/index.ts +2 -1
- package/src/interceptors/index.ts +2 -1
- package/src/interceptors/locusRouteToken.ts +80 -0
- package/src/locus-info/controlsUtils.ts +18 -0
- package/src/locus-info/index.ts +14 -4
- package/src/meeting/in-meeting-actions.ts +4 -0
- package/src/meeting/index.ts +67 -20
- package/src/meeting/request.ts +38 -0
- package/src/meeting/util.ts +3 -0
- package/src/member/index.ts +10 -0
- package/src/member/util.ts +14 -0
- package/test/unit/spec/controls-options-manager/index.js +47 -0
- package/test/unit/spec/fixture/locus.js +1 -0
- package/test/unit/spec/interceptors/locusRouteToken.ts +87 -0
- package/test/unit/spec/locus-info/index.js +39 -0
- package/test/unit/spec/meeting/in-meeting-actions.ts +2 -0
- package/test/unit/spec/meeting/index.js +41 -2
- package/test/unit/spec/meeting/utils.js +1 -0
- package/test/unit/spec/member/util.js +24 -0
package/src/locus-info/index.ts
CHANGED
@@ -343,7 +343,7 @@ export default class LocusInfo extends EventsScope {
|
|
343
343
|
// For 1:1 space meeting the conversation Url does not exist in locus.conversation
|
344
344
|
this.updateConversationUrl(locus.conversationUrl, locus.info);
|
345
345
|
this.updateControls(locus.controls, locus.self);
|
346
|
-
this.updateLocusUrl(locus.url);
|
346
|
+
this.updateLocusUrl(locus.url, ControlsUtils.isMainSessionDTO(locus));
|
347
347
|
this.updateFullState(locus.fullState);
|
348
348
|
this.updateMeetingInfo(locus.info);
|
349
349
|
this.updateEmbeddedApps(locus.embeddedApps);
|
@@ -549,7 +549,7 @@ export default class LocusInfo extends EventsScope {
|
|
549
549
|
this.updateCreated(locus.created);
|
550
550
|
this.updateFullState(locus.fullState);
|
551
551
|
this.updateHostInfo(locus.host);
|
552
|
-
this.updateLocusUrl(locus.url);
|
552
|
+
this.updateLocusUrl(locus.url, ControlsUtils.isMainSessionDTO(locus));
|
553
553
|
this.updateMeetingInfo(locus.info, locus.self);
|
554
554
|
this.updateMediaShares(locus.mediaShares);
|
555
555
|
this.updateParticipantsUrl(locus.participantsUrl);
|
@@ -895,6 +895,7 @@ export default class LocusInfo extends EventsScope {
|
|
895
895
|
hasAnnotationControlChanged,
|
896
896
|
hasRemoteDesktopControlChanged,
|
897
897
|
hasPollingQAControlChanged,
|
898
|
+
hasAutoEndMeetingChanged,
|
898
899
|
},
|
899
900
|
current,
|
900
901
|
} = ControlsUtils.getControls(this.controls, controls);
|
@@ -1169,6 +1170,14 @@ export default class LocusInfo extends EventsScope {
|
|
1169
1170
|
);
|
1170
1171
|
}
|
1171
1172
|
|
1173
|
+
if (hasAutoEndMeetingChanged) {
|
1174
|
+
this.emitScoped(
|
1175
|
+
{file: 'locus-info', function: 'updateControls'},
|
1176
|
+
LOCUSINFO.EVENTS.CONTROLS_AUTO_END_MEETING_WARNING_CHANGED,
|
1177
|
+
{state: current.autoEndMeetingWarning}
|
1178
|
+
);
|
1179
|
+
}
|
1180
|
+
|
1172
1181
|
this.controls = controls;
|
1173
1182
|
}
|
1174
1183
|
}
|
@@ -1732,10 +1741,11 @@ export default class LocusInfo extends EventsScope {
|
|
1732
1741
|
/**
|
1733
1742
|
* handles when the locus.url is updated
|
1734
1743
|
* @param {String} url
|
1744
|
+
* @param {Boolean} isMainLocus
|
1735
1745
|
* @returns {undefined}
|
1736
1746
|
* emits internal event locus_info_update_url
|
1737
1747
|
*/
|
1738
|
-
updateLocusUrl(url: string) {
|
1748
|
+
updateLocusUrl(url: string, isMainLocus = true) {
|
1739
1749
|
if (url && this.url !== url) {
|
1740
1750
|
this.url = url;
|
1741
1751
|
this.updateMeeting({locusUrl: url});
|
@@ -1745,7 +1755,7 @@ export default class LocusInfo extends EventsScope {
|
|
1745
1755
|
function: 'updateLocusUrl',
|
1746
1756
|
},
|
1747
1757
|
EVENTS.LOCUS_INFO_UPDATE_URL,
|
1748
|
-
url
|
1758
|
+
{url, isMainLocus}
|
1749
1759
|
);
|
1750
1760
|
}
|
1751
1761
|
}
|
@@ -92,6 +92,7 @@ interface IInMeetingActions {
|
|
92
92
|
canDoVideo?: boolean;
|
93
93
|
canAnnotate?: boolean;
|
94
94
|
canUseVoip?: boolean;
|
95
|
+
showAutoEndMeetingWarning?: boolean;
|
95
96
|
supportHQV?: boolean;
|
96
97
|
supportHDV?: boolean;
|
97
98
|
canShareWhiteBoard?: boolean;
|
@@ -284,6 +285,8 @@ export default class InMeetingActions implements IInMeetingActions {
|
|
284
285
|
|
285
286
|
canUseVoip = null;
|
286
287
|
|
288
|
+
showAutoEndMeetingWarning = null;
|
289
|
+
|
287
290
|
supportHQV = null;
|
288
291
|
|
289
292
|
enforceVirtualBackground = null;
|
@@ -405,6 +408,7 @@ export default class InMeetingActions implements IInMeetingActions {
|
|
405
408
|
canShareFile: this.canShareFile,
|
406
409
|
canShareApplication: this.canShareApplication,
|
407
410
|
canShareCamera: this.canShareCamera,
|
411
|
+
showAutoEndMeetingWarning: this.showAutoEndMeetingWarning,
|
408
412
|
canShareDesktop: this.canShareDesktop,
|
409
413
|
canShareContent: this.canShareContent,
|
410
414
|
canTransferFile: this.canTransferFile,
|
package/src/meeting/index.ts
CHANGED
@@ -2976,6 +2976,18 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
2976
2976
|
);
|
2977
2977
|
});
|
2978
2978
|
|
2979
|
+
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_AUTO_END_MEETING_WARNING_CHANGED, ({state}) => {
|
2980
|
+
Trigger.trigger(
|
2981
|
+
this,
|
2982
|
+
{
|
2983
|
+
file: 'meeting/index',
|
2984
|
+
function: 'setupLocusControlsListener',
|
2985
|
+
},
|
2986
|
+
EVENT_TRIGGERS.MEETING_CONTROLS_AUTO_END_MEETING_WARNING_UPDATED,
|
2987
|
+
{state}
|
2988
|
+
);
|
2989
|
+
});
|
2990
|
+
|
2979
2991
|
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_ANNOTATION_CHANGED, ({state}) => {
|
2980
2992
|
Trigger.trigger(
|
2981
2993
|
this,
|
@@ -3356,27 +3368,31 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
3356
3368
|
* @memberof Meeting
|
3357
3369
|
*/
|
3358
3370
|
private setUpLocusUrlListener() {
|
3359
|
-
this.locusInfo.on(
|
3360
|
-
|
3361
|
-
|
3362
|
-
|
3363
|
-
|
3364
|
-
|
3365
|
-
|
3366
|
-
|
3367
|
-
|
3368
|
-
|
3371
|
+
this.locusInfo.on(
|
3372
|
+
EVENTS.LOCUS_INFO_UPDATE_URL,
|
3373
|
+
(payload: {url: string; isMainLocus?: boolean}) => {
|
3374
|
+
const {url, isMainLocus} = payload;
|
3375
|
+
this.members.locusUrlUpdate(url);
|
3376
|
+
this.breakouts.locusUrlUpdate(url);
|
3377
|
+
this.simultaneousInterpretation.locusUrlUpdate(url);
|
3378
|
+
this.annotation.locusUrlUpdate(url);
|
3379
|
+
this.locusUrl = url;
|
3380
|
+
this.locusId = this.locusUrl?.split('/').pop();
|
3381
|
+
this.recordingController.setLocusUrl(this.locusUrl);
|
3382
|
+
this.controlsOptionsManager.setLocusUrl(this.locusUrl, !!isMainLocus);
|
3383
|
+
this.webinar.locusUrlUpdate(url);
|
3369
3384
|
|
3370
|
-
|
3371
|
-
|
3372
|
-
|
3373
|
-
|
3374
|
-
|
3375
|
-
|
3376
|
-
|
3377
|
-
|
3378
|
-
|
3379
|
-
|
3385
|
+
Trigger.trigger(
|
3386
|
+
this,
|
3387
|
+
{
|
3388
|
+
file: 'meeting/index',
|
3389
|
+
function: 'setUpLocusSelfListener',
|
3390
|
+
},
|
3391
|
+
EVENT_TRIGGERS.MEETING_LOCUS_URL_UPDATE,
|
3392
|
+
{locusUrl: url}
|
3393
|
+
);
|
3394
|
+
}
|
3395
|
+
);
|
3380
3396
|
}
|
3381
3397
|
|
3382
3398
|
/**
|
@@ -4219,6 +4235,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
4219
4235
|
this.userDisplayHints,
|
4220
4236
|
this.selfUserPolicies
|
4221
4237
|
),
|
4238
|
+
showAutoEndMeetingWarning: MeetingUtil.showAutoEndMeetingWarning(this.userDisplayHints),
|
4222
4239
|
canRaiseHand: MeetingUtil.canUserRaiseHand(this.userDisplayHints),
|
4223
4240
|
canLowerAllHands: MeetingUtil.canUserLowerAllHands(this.userDisplayHints),
|
4224
4241
|
canLowerSomeoneElsesHand: MeetingUtil.canUserLowerSomeoneElsesHand(this.userDisplayHints),
|
@@ -9449,6 +9466,36 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
9449
9466
|
return Promise.reject(new Error('Error sending reaction, service url not found.'));
|
9450
9467
|
}
|
9451
9468
|
|
9469
|
+
/**
|
9470
|
+
* Extend the current meeting duration.
|
9471
|
+
*
|
9472
|
+
* @param {number} extensionMinutes - how many minutes to extend
|
9473
|
+
* @returns {Promise}
|
9474
|
+
* @public
|
9475
|
+
* @memberof Meeting
|
9476
|
+
*/
|
9477
|
+
public extendMeeting({
|
9478
|
+
meetingPolicyUrl,
|
9479
|
+
meetingInstanceId,
|
9480
|
+
participantId,
|
9481
|
+
extensionMinutes = 30,
|
9482
|
+
}) {
|
9483
|
+
if (!meetingInstanceId || !participantId) {
|
9484
|
+
return Promise.reject(new Error('Missing meetingInstanceId or participantId'));
|
9485
|
+
}
|
9486
|
+
|
9487
|
+
if (!meetingPolicyUrl) {
|
9488
|
+
return Promise.reject(new Error('Missing meetingPolicyUrl'));
|
9489
|
+
}
|
9490
|
+
|
9491
|
+
return this.meetingRequest.extendMeeting({
|
9492
|
+
meetingInstanceId,
|
9493
|
+
participantId,
|
9494
|
+
extensionMinutes,
|
9495
|
+
meetingPolicyUrl,
|
9496
|
+
});
|
9497
|
+
}
|
9498
|
+
|
9452
9499
|
/**
|
9453
9500
|
* Method to enable or disable reactions inside the meeting.
|
9454
9501
|
*
|
package/src/meeting/request.ts
CHANGED
@@ -886,6 +886,44 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
886
886
|
});
|
887
887
|
}
|
888
888
|
|
889
|
+
/**
|
890
|
+
* Extend the current meeting duration.
|
891
|
+
*
|
892
|
+
* @param {Object} params - Parameters for extending the meeting.
|
893
|
+
* @param {string} params.meetingInstanceId - The unique ID of the meeting instance.
|
894
|
+
* @param {string} params.participantId - The ID of the participant requesting the extension.
|
895
|
+
* @param {number} params.extensionMinutes - The number of minutes to extend the meeting by.
|
896
|
+
* @param {string} params.meetingPolicyUrl - The base URL for meeting policy service (dynamic, from locus links)
|
897
|
+
* @returns {Promise<any>} A promise that resolves with the server response.
|
898
|
+
*/
|
899
|
+
extendMeeting({
|
900
|
+
meetingInstanceId,
|
901
|
+
participantId,
|
902
|
+
extensionMinutes,
|
903
|
+
meetingPolicyUrl,
|
904
|
+
}: {
|
905
|
+
meetingInstanceId: string;
|
906
|
+
participantId: string;
|
907
|
+
extensionMinutes: number;
|
908
|
+
meetingPolicyUrl: string;
|
909
|
+
}) {
|
910
|
+
if (!meetingPolicyUrl) {
|
911
|
+
return Promise.reject(new Error('meetingPolicyUrl is required'));
|
912
|
+
}
|
913
|
+
const uri = `${meetingPolicyUrl}/continueMeeting`;
|
914
|
+
|
915
|
+
// @ts-ignore
|
916
|
+
return this.request({
|
917
|
+
method: HTTP_VERBS.POST,
|
918
|
+
uri,
|
919
|
+
body: {
|
920
|
+
meetingInstanceId,
|
921
|
+
requestParticipantId: participantId,
|
922
|
+
extensionMinutes,
|
923
|
+
},
|
924
|
+
});
|
925
|
+
}
|
926
|
+
|
889
927
|
/**
|
890
928
|
* Make a network request to enable or disable reactions.
|
891
929
|
* @param {boolean} options.enable - determines if we need to enable or disable.
|
package/src/meeting/util.ts
CHANGED
@@ -654,6 +654,9 @@ const MeetingUtil = {
|
|
654
654
|
|
655
655
|
waitingForOthersToJoin: (displayHints) => displayHints.includes(DISPLAY_HINTS.WAITING_FOR_OTHERS),
|
656
656
|
|
657
|
+
showAutoEndMeetingWarning: (displayHints) =>
|
658
|
+
displayHints.includes(DISPLAY_HINTS.SHOW_AUTO_END_MEETING_WARNING),
|
659
|
+
|
657
660
|
canSendReactions: (originalValue, displayHints) => {
|
658
661
|
if (displayHints.includes(DISPLAY_HINTS.REACTIONS_ACTIVE)) {
|
659
662
|
return true;
|
package/src/member/index.ts
CHANGED
@@ -42,6 +42,7 @@ export default class Member {
|
|
42
42
|
status: any;
|
43
43
|
supportsBreakouts: boolean;
|
44
44
|
supportsInterpretation: boolean;
|
45
|
+
supportsSingleUserAutoEndMeeting: boolean;
|
45
46
|
supportLiveAnnotation: boolean;
|
46
47
|
type: any;
|
47
48
|
namespace = MEETINGS;
|
@@ -130,6 +131,13 @@ export default class Member {
|
|
130
131
|
* @memberof Member
|
131
132
|
*/
|
132
133
|
this.supportsBreakouts = null;
|
134
|
+
/**
|
135
|
+
* @instance
|
136
|
+
* @type {Boolean}
|
137
|
+
* @public
|
138
|
+
* @memberof Member
|
139
|
+
*/
|
140
|
+
this.supportsSingleUserAutoEndMeeting = null;
|
133
141
|
/**
|
134
142
|
* @instance
|
135
143
|
* @type {Boolean}
|
@@ -339,6 +347,8 @@ export default class Member {
|
|
339
347
|
this.isVideoMuted = MemberUtil.isVideoMuted(participant);
|
340
348
|
this.isHandRaised = MemberUtil.isHandRaised(participant);
|
341
349
|
this.supportsBreakouts = MemberUtil.isBreakoutsSupported(participant);
|
350
|
+
this.supportsSingleUserAutoEndMeeting =
|
351
|
+
MemberUtil.isSupportsSingleUserAutoEndMeeting(participant);
|
342
352
|
this.supportsInterpretation = MemberUtil.isInterpretationSupported(participant);
|
343
353
|
this.supportLiveAnnotation = MemberUtil.isLiveAnnotationSupported(participant);
|
344
354
|
this.isGuest = MemberUtil.isGuest(participant);
|
package/src/member/util.ts
CHANGED
@@ -207,6 +207,20 @@ const MemberUtil = {
|
|
207
207
|
return !participant.doesNotSupportBreakouts;
|
208
208
|
},
|
209
209
|
|
210
|
+
/**
|
211
|
+
* @param {Object} participant - The locus participant object.
|
212
|
+
* @returns {Boolean}
|
213
|
+
*/
|
214
|
+
isSupportsSingleUserAutoEndMeeting: (participant) => {
|
215
|
+
if (!participant) {
|
216
|
+
throw new ParameterError(
|
217
|
+
'Single user auto end meeting support could not be processed, participant is undefined.'
|
218
|
+
);
|
219
|
+
}
|
220
|
+
|
221
|
+
return !participant.doesNotSupportSingleUserAutoEndMeeting;
|
222
|
+
},
|
223
|
+
|
210
224
|
/**
|
211
225
|
* @param {Object} participant - The locus participant object.
|
212
226
|
* @returns {Boolean}
|
@@ -133,6 +133,7 @@ describe('plugin-meetings', () => {
|
|
133
133
|
|
134
134
|
manager.set({
|
135
135
|
locusUrl: 'test/id',
|
136
|
+
mainLocusUrl: '',
|
136
137
|
displayHints: [],
|
137
138
|
});
|
138
139
|
});
|
@@ -201,6 +202,38 @@ describe('plugin-meetings', () => {
|
|
201
202
|
Util.canUpdate = restorable;
|
202
203
|
});
|
203
204
|
});
|
205
|
+
|
206
|
+
it('should call request with mainLocusUrl and locusUrl as authorizingLocusUrl if mainLocusUrl is exist and not same with locusUrl', () => {
|
207
|
+
const restorable = Util.canUpdate;
|
208
|
+
Util.canUpdate = sinon.stub().returns(true);
|
209
|
+
manager.mainLocusUrl = 'test/main';
|
210
|
+
|
211
|
+
const audio = {scope: 'audio', properties: {a: 1, b: 2}};
|
212
|
+
const reactions = {scope: 'reactions', properties: {c: 3, d: 4}};
|
213
|
+
|
214
|
+
return manager.update(audio, reactions)
|
215
|
+
.then(() => {
|
216
|
+
assert.calledWith(request.request, {
|
217
|
+
uri: 'test/main/controls',
|
218
|
+
body: {
|
219
|
+
audio: audio.properties,
|
220
|
+
authorizingLocusUrl: 'test/id'
|
221
|
+
},
|
222
|
+
method: HTTP_VERBS.PATCH,
|
223
|
+
});
|
224
|
+
|
225
|
+
assert.calledWith(request.request, {
|
226
|
+
uri: 'test/main/controls',
|
227
|
+
body: {
|
228
|
+
reactions: reactions.properties,
|
229
|
+
authorizingLocusUrl: 'test/id'
|
230
|
+
},
|
231
|
+
method: HTTP_VERBS.PATCH,
|
232
|
+
});
|
233
|
+
|
234
|
+
Util.canUpdate = restorable;
|
235
|
+
});
|
236
|
+
});
|
204
237
|
});
|
205
238
|
|
206
239
|
describe('Mute/Unmute All', () => {
|
@@ -214,6 +247,7 @@ describe('plugin-meetings', () => {
|
|
214
247
|
|
215
248
|
manager.set({
|
216
249
|
locusUrl: 'test/id',
|
250
|
+
mainLocusUrl: '',
|
217
251
|
displayHints: [],
|
218
252
|
})
|
219
253
|
});
|
@@ -305,6 +339,19 @@ describe('plugin-meetings', () => {
|
|
305
339
|
|
306
340
|
assert.deepEqual(result, request.request.firstCall.returnValue);
|
307
341
|
});
|
342
|
+
|
343
|
+
it('request with mainLocusUrl and make locusUrl as authorizingLocusUrl if mainLocusUrl is exist and not same with locusUrl', () => {
|
344
|
+
manager.setDisplayHints(['MUTE_ALL', 'DISABLE_HARD_MUTE', 'DISABLE_MUTE_ON_ENTRY']);
|
345
|
+
manager.mainLocusUrl = `test/main`;
|
346
|
+
|
347
|
+
const result = manager.setMuteAll(true, true, true, ['attendee']);
|
348
|
+
|
349
|
+
assert.calledWith(request.request, { uri: 'test/main/controls',
|
350
|
+
body: { audio: { muted: true, disallowUnmute: true, muteOnEntry: true, roles: ['attendee'] }, authorizingLocusUrl: 'test/id' },
|
351
|
+
method: HTTP_VERBS.PATCH});
|
352
|
+
|
353
|
+
assert.deepEqual(result, request.request.firstCall.returnValue);
|
354
|
+
});
|
308
355
|
});
|
309
356
|
});
|
310
357
|
});
|
@@ -0,0 +1,87 @@
|
|
1
|
+
/*!
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
3
|
+
*/
|
4
|
+
|
5
|
+
/* eslint-disable camelcase */
|
6
|
+
import 'jsdom-global/register';
|
7
|
+
import {assert} from '@webex/test-helper-chai';
|
8
|
+
import MockWebex from '@webex/test-helper-mock-webex';
|
9
|
+
import {LocusRouteTokenInterceptor} from '@webex/plugin-meetings/src/interceptors';
|
10
|
+
import Meetings from '@webex/plugin-meetings';
|
11
|
+
|
12
|
+
const X_CISCO_PART_ROUTE_TOKEN = 'X-Cisco-Part-Route-Token';
|
13
|
+
|
14
|
+
describe('LocusRouteTokenInterceptor', () => {
|
15
|
+
let interceptor, webex;
|
16
|
+
const TEST_LOCUS_ID = '0f1eba56-91e2-2a11-9b2b-1e2da077f066';
|
17
|
+
beforeEach(() => {
|
18
|
+
webex = new MockWebex({
|
19
|
+
children: {
|
20
|
+
meetings: Meetings,
|
21
|
+
},
|
22
|
+
});
|
23
|
+
interceptor = Reflect.apply(LocusRouteTokenInterceptor.create, webex, []);
|
24
|
+
});
|
25
|
+
|
26
|
+
it('getLocusIdByRequestUrl should return locusId from url', () => {
|
27
|
+
const url = `https://locus-test.webex.com/locus/api/v1/loci/${TEST_LOCUS_ID}/foo`;
|
28
|
+
assert.equal(interceptor.getLocusIdByRequestUrl(url), TEST_LOCUS_ID);
|
29
|
+
});
|
30
|
+
|
31
|
+
it('getLocusIdByRequestUrl should return undefined when no locusId in url', () => {
|
32
|
+
const url = 'https://locus-test.webex.com/locus/api/v1/foo';
|
33
|
+
assert.isUndefined(interceptor.getLocusIdByRequestUrl(url));
|
34
|
+
});
|
35
|
+
|
36
|
+
it('getLocusIdByRequestUrl should return undefined when url is undefined', () => {
|
37
|
+
assert.isUndefined(interceptor.getLocusIdByRequestUrl(undefined));
|
38
|
+
});
|
39
|
+
|
40
|
+
it('onResponse should store route token when header exists', async () => {
|
41
|
+
const response = {
|
42
|
+
headers: {
|
43
|
+
[X_CISCO_PART_ROUTE_TOKEN]: 'test-token',
|
44
|
+
},
|
45
|
+
};
|
46
|
+
|
47
|
+
const result = await interceptor.onResponse(
|
48
|
+
{
|
49
|
+
uri: `https://locus-test.webex.com/locus/api/v1/loci/${TEST_LOCUS_ID}/foo`,
|
50
|
+
},
|
51
|
+
response
|
52
|
+
);
|
53
|
+
assert.equal(result, response);
|
54
|
+
assert.equal(interceptor.getToken(TEST_LOCUS_ID), 'test-token');
|
55
|
+
});
|
56
|
+
|
57
|
+
it('onResponse should not store token when header missing', async () => {
|
58
|
+
interceptor.updateToken(TEST_LOCUS_ID);
|
59
|
+
const response = {headers: {}};
|
60
|
+
|
61
|
+
await interceptor.onResponse({}, response);
|
62
|
+
assert.isUndefined(interceptor.getToken(TEST_LOCUS_ID));
|
63
|
+
});
|
64
|
+
|
65
|
+
it('onRequest should attach token to headers when token exists', async () => {
|
66
|
+
interceptor.updateToken(TEST_LOCUS_ID, 'abc123');
|
67
|
+
|
68
|
+
const options = {
|
69
|
+
headers: {},
|
70
|
+
uri: `https://locus-test.webex.com/locus/api/v1/loci/${TEST_LOCUS_ID}/foo`,
|
71
|
+
};
|
72
|
+
const result = await interceptor.onRequest(options);
|
73
|
+
assert.equal(result.headers[X_CISCO_PART_ROUTE_TOKEN], 'abc123');
|
74
|
+
});
|
75
|
+
|
76
|
+
it('onRequest should not attach token if none is stored', async () => {
|
77
|
+
interceptor.updateToken(TEST_LOCUS_ID);
|
78
|
+
const options = {headers: {}};
|
79
|
+
const result = await interceptor.onRequest(options);
|
80
|
+
assert.isUndefined(result.headers[X_CISCO_PART_ROUTE_TOKEN]);
|
81
|
+
});
|
82
|
+
|
83
|
+
it('updateToken & getToken should work as pair', () => {
|
84
|
+
interceptor.updateToken(TEST_LOCUS_ID, 'abc456');
|
85
|
+
assert.equal(interceptor.getToken(TEST_LOCUS_ID), 'abc456');
|
86
|
+
});
|
87
|
+
});
|
@@ -3020,6 +3020,45 @@ describe('plugin-meetings', () => {
|
|
3020
3020
|
});
|
3021
3021
|
});
|
3022
3022
|
|
3023
|
+
describe('#updateLocusUrl', () => {
|
3024
|
+
it('trigger LOCUS_INFO_UPDATE_URL event with isMainLocus is true as default', () => {
|
3025
|
+
const fakeUrl = "https://fake.com/locus";
|
3026
|
+
locusInfo.emitScoped = sinon.stub();
|
3027
|
+
locusInfo.updateLocusUrl(fakeUrl);
|
3028
|
+
|
3029
|
+
assert.calledWith(
|
3030
|
+
locusInfo.emitScoped,
|
3031
|
+
{
|
3032
|
+
file: 'locus-info',
|
3033
|
+
function: 'updateLocusUrl',
|
3034
|
+
},
|
3035
|
+
EVENTS.LOCUS_INFO_UPDATE_URL,
|
3036
|
+
{
|
3037
|
+
url: fakeUrl,
|
3038
|
+
isMainLocus: true
|
3039
|
+
},
|
3040
|
+
);
|
3041
|
+
});
|
3042
|
+
it('trigger LOCUS_INFO_UPDATE_URL event with isMainLocus is false', () => {
|
3043
|
+
const fakeUrl = "https://fake.com/locus";
|
3044
|
+
locusInfo.emitScoped = sinon.stub();
|
3045
|
+
locusInfo.updateLocusUrl(fakeUrl, false);
|
3046
|
+
|
3047
|
+
assert.calledWith(
|
3048
|
+
locusInfo.emitScoped,
|
3049
|
+
{
|
3050
|
+
file: 'locus-info',
|
3051
|
+
function: 'updateLocusUrl',
|
3052
|
+
},
|
3053
|
+
EVENTS.LOCUS_INFO_UPDATE_URL,
|
3054
|
+
{
|
3055
|
+
url: fakeUrl,
|
3056
|
+
isMainLocus: false
|
3057
|
+
},
|
3058
|
+
);
|
3059
|
+
});
|
3060
|
+
});
|
3061
|
+
|
3023
3062
|
// semi-integration tests that use real LocusInfo with real Parser
|
3024
3063
|
// and test various scenarios related to handling out-of-order Locus delta events
|
3025
3064
|
describe('handling of out-of-order Locus delta events', () => {
|
@@ -86,6 +86,7 @@ describe('plugin-meetings', () => {
|
|
86
86
|
canDoVideo: null,
|
87
87
|
canAnnotate: null,
|
88
88
|
canUseVoip: null,
|
89
|
+
showAutoEndMeetingWarning: null,
|
89
90
|
supportHQV: null,
|
90
91
|
supportHDV: null,
|
91
92
|
canShareWhiteBoard: null,
|
@@ -197,6 +198,7 @@ describe('plugin-meetings', () => {
|
|
197
198
|
'canRealtimeCloseCaption',
|
198
199
|
'canRealtimeCloseCaptionManual',
|
199
200
|
'canChat',
|
201
|
+
'showAutoEndMeetingWarning',
|
200
202
|
'canDoVideo',
|
201
203
|
'canAnnotate',
|
202
204
|
'canUseVoip',
|
@@ -10471,6 +10471,24 @@ describe('plugin-meetings', () => {
|
|
10471
10471
|
);
|
10472
10472
|
});
|
10473
10473
|
|
10474
|
+
it('listens to CONTROLS_AUTO_END_MEETING_WARNING_CHANGED', async () => {
|
10475
|
+
const state = {example: 'value'};
|
10476
|
+
|
10477
|
+
await meeting.locusInfo.emitScoped(
|
10478
|
+
{function: 'test', file: 'test'},
|
10479
|
+
LOCUSINFO.EVENTS.CONTROLS_AUTO_END_MEETING_WARNING_CHANGED,
|
10480
|
+
{state}
|
10481
|
+
);
|
10482
|
+
|
10483
|
+
assert.calledWith(
|
10484
|
+
TriggerProxy.trigger,
|
10485
|
+
meeting,
|
10486
|
+
{file: 'meeting/index', function: 'setupLocusControlsListener'},
|
10487
|
+
EVENT_TRIGGERS.MEETING_CONTROLS_AUTO_END_MEETING_WARNING_UPDATED,
|
10488
|
+
{state}
|
10489
|
+
);
|
10490
|
+
});
|
10491
|
+
|
10474
10492
|
it('listens to CONTROLS_REMOTE_DESKTOP_CONTROL_CHANGED', async () => {
|
10475
10493
|
const state = {example: 'value'};
|
10476
10494
|
|
@@ -10550,6 +10568,7 @@ describe('plugin-meetings', () => {
|
|
10550
10568
|
describe('#setUpLocusUrlListener', () => {
|
10551
10569
|
it('listens to the locus url update event', (done) => {
|
10552
10570
|
const newLocusUrl = 'newLocusUrl/12345';
|
10571
|
+
const payload = {url: newLocusUrl}
|
10553
10572
|
|
10554
10573
|
meeting.members = {locusUrlUpdate: sinon.stub().returns(Promise.resolve(test1))};
|
10555
10574
|
meeting.recordingController = {setLocusUrl: sinon.stub().returns(undefined)};
|
@@ -10563,14 +10582,14 @@ describe('plugin-meetings', () => {
|
|
10563
10582
|
meeting.locusInfo.emit(
|
10564
10583
|
{function: 'test', file: 'test'},
|
10565
10584
|
'LOCUS_INFO_UPDATE_URL',
|
10566
|
-
|
10585
|
+
payload
|
10567
10586
|
);
|
10568
10587
|
assert.calledWith(meeting.members.locusUrlUpdate, newLocusUrl);
|
10569
10588
|
assert.calledOnceWithExactly(meeting.breakouts.locusUrlUpdate, newLocusUrl);
|
10570
10589
|
assert.calledOnceWithExactly(meeting.annotation.locusUrlUpdate, newLocusUrl);
|
10571
10590
|
assert.calledWith(meeting.members.locusUrlUpdate, newLocusUrl);
|
10572
10591
|
assert.calledWith(meeting.recordingController.setLocusUrl, newLocusUrl);
|
10573
|
-
assert.calledWith(meeting.controlsOptionsManager.setLocusUrl, newLocusUrl);
|
10592
|
+
assert.calledWith(meeting.controlsOptionsManager.setLocusUrl, newLocusUrl, false);
|
10574
10593
|
assert.calledWith(meeting.simultaneousInterpretation.locusUrlUpdate, newLocusUrl);
|
10575
10594
|
assert.calledWith(meeting.webinar.locusUrlUpdate, newLocusUrl);
|
10576
10595
|
assert.equal(meeting.locusUrl, newLocusUrl);
|
@@ -10588,6 +10607,22 @@ describe('plugin-meetings', () => {
|
|
10588
10607
|
{locusUrl: 'newLocusUrl/12345'}
|
10589
10608
|
);
|
10590
10609
|
|
10610
|
+
done();
|
10611
|
+
});
|
10612
|
+
it('update mainLocusUrl for controlsOptionManager if payload.isMainLocus as true', (done) => {
|
10613
|
+
const newLocusUrl = 'newLocusUrl/12345';
|
10614
|
+
const payload = {url: newLocusUrl, isMainLocus: true}
|
10615
|
+
|
10616
|
+
meeting.controlsOptionsManager = {setLocusUrl: sinon.stub().returns(undefined)};
|
10617
|
+
|
10618
|
+
meeting.locusInfo.emit(
|
10619
|
+
{function: 'test', file: 'test'},
|
10620
|
+
'LOCUS_INFO_UPDATE_URL',
|
10621
|
+
payload
|
10622
|
+
);
|
10623
|
+
|
10624
|
+
assert.calledWith(meeting.controlsOptionsManager.setLocusUrl, newLocusUrl, true);
|
10625
|
+
|
10591
10626
|
done();
|
10592
10627
|
});
|
10593
10628
|
});
|
@@ -11426,6 +11461,7 @@ describe('plugin-meetings', () => {
|
|
11426
11461
|
let canShareWhiteBoardSpy;
|
11427
11462
|
let canMoveToLobbySpy;
|
11428
11463
|
let isSpokenLanguageAutoDetectionEnabledSpy;
|
11464
|
+
let showAutoEndMeetingWarningSpy;
|
11429
11465
|
// Due to import tree issues, hasHints must be stubed within the scope of the `it`.
|
11430
11466
|
|
11431
11467
|
beforeEach(() => {
|
@@ -11457,6 +11493,7 @@ describe('plugin-meetings', () => {
|
|
11457
11493
|
canUserRenameOthersSpy = sinon.spy(MeetingUtil, 'canUserRenameOthers');
|
11458
11494
|
canShareWhiteBoardSpy = sinon.spy(MeetingUtil, 'canShareWhiteBoard');
|
11459
11495
|
canMoveToLobbySpy = sinon.spy(MeetingUtil, 'canMoveToLobby');
|
11496
|
+
showAutoEndMeetingWarningSpy = sinon.spy(MeetingUtil, 'showAutoEndMeetingWarning');
|
11460
11497
|
isSpokenLanguageAutoDetectionEnabledSpy = sinon.spy(MeetingUtil, 'isSpokenLanguageAutoDetectionEnabled');
|
11461
11498
|
|
11462
11499
|
});
|
@@ -11464,6 +11501,7 @@ describe('plugin-meetings', () => {
|
|
11464
11501
|
afterEach(() => {
|
11465
11502
|
inMeetingActionsSetSpy.restore();
|
11466
11503
|
waitingForOthersToJoinSpy.restore();
|
11504
|
+
showAutoEndMeetingWarningSpy.restore();
|
11467
11505
|
});
|
11468
11506
|
|
11469
11507
|
forEach(
|
@@ -12011,6 +12049,7 @@ describe('plugin-meetings', () => {
|
|
12011
12049
|
assert.calledWith(canUserRenameOthersSpy, userDisplayHints);
|
12012
12050
|
assert.calledWith(canShareWhiteBoardSpy, userDisplayHints, selfUserPolicies);
|
12013
12051
|
assert.calledWith(canMoveToLobbySpy, userDisplayHints);
|
12052
|
+
assert.calledWith(showAutoEndMeetingWarningSpy, userDisplayHints);
|
12014
12053
|
assert.calledWith(isSpokenLanguageAutoDetectionEnabledSpy, userDisplayHints);
|
12015
12054
|
|
12016
12055
|
assert.calledWith(ControlsOptionsUtil.hasHints, {
|
@@ -985,6 +985,7 @@ describe('plugin-meetings', () => {
|
|
985
985
|
{functionName: 'isRealTimeTranslationEnabled', displayHint: 'DISPLAY_REAL_TIME_TRANSLATION'},
|
986
986
|
{functionName: 'canSelectSpokenLanguages', displayHint: 'DISPLAY_NON_ENGLISH_ASR'},
|
987
987
|
{functionName: 'waitingForOthersToJoin', displayHint: 'WAITING_FOR_OTHERS'},
|
988
|
+
{functionName: 'showAutoEndMeetingWarning', displayHint: 'SHOW_AUTO_END_MEETING_WARNING'},
|
988
989
|
].forEach(({functionName, displayHint}) => {
|
989
990
|
describe(functionName, () => {
|
990
991
|
it('works as expected', () => {
|