@webex/plugin-meetings 2.60.0-next.2 → 2.60.0-next.4
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/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/parser.js +5 -5
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/media/index.js +6 -5
- package/dist/media/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 +121 -47
- package/dist/meeting/index.js.map +1 -1
- package/dist/meetings/index.js +17 -9
- package/dist/meetings/index.js.map +1 -1
- package/dist/metrics/constants.js +2 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/reconnection-manager/index.js +1 -2
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/webinar/index.js +1 -1
- package/package.json +21 -21
- package/src/locus-info/parser.ts +6 -6
- package/src/media/index.ts +5 -5
- package/src/meeting/in-meeting-actions.ts +4 -0
- package/src/meeting/index.ts +111 -30
- package/src/meetings/index.ts +17 -10
- package/src/metrics/constants.ts +2 -0
- package/src/reconnection-manager/index.ts +1 -2
- package/test/unit/spec/media/index.ts +20 -4
- package/test/unit/spec/meeting/in-meeting-actions.ts +2 -0
- package/test/unit/spec/meeting/index.js +243 -47
- package/test/unit/spec/meetings/index.js +84 -8
- package/test/unit/spec/reconnection-manager/index.js +33 -18
|
@@ -308,6 +308,7 @@ describe('plugin-meetings', () => {
|
|
|
308
308
|
assert.equal(meeting.resource, uuid2);
|
|
309
309
|
assert.equal(meeting.deviceUrl, uuid3);
|
|
310
310
|
assert.equal(meeting.correlationId, correlationId);
|
|
311
|
+
assert.deepEqual(meeting.callStateForMetrics, {correlationId});
|
|
311
312
|
assert.deepEqual(meeting.meetingInfo, {});
|
|
312
313
|
assert.instanceOf(meeting.members, Members);
|
|
313
314
|
assert.calledOnceWithExactly(
|
|
@@ -375,6 +376,34 @@ describe('plugin-meetings', () => {
|
|
|
375
376
|
}
|
|
376
377
|
);
|
|
377
378
|
assert.equal(newMeeting.correlationId, newMeeting.id);
|
|
379
|
+
assert.deepEqual(newMeeting.callStateForMetrics, {correlationId: newMeeting.id});
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
it('correlationId can be provided in callStateForMetrics', () => {
|
|
383
|
+
const newMeeting = new Meeting(
|
|
384
|
+
{
|
|
385
|
+
userId: uuid1,
|
|
386
|
+
resource: uuid2,
|
|
387
|
+
deviceUrl: uuid3,
|
|
388
|
+
locus: {url: url1},
|
|
389
|
+
destination: testDestination,
|
|
390
|
+
destinationType: _MEETING_ID_,
|
|
391
|
+
callStateForMetrics: {
|
|
392
|
+
correlationId: uuid4,
|
|
393
|
+
joinTrigger: 'fake-join-trigger',
|
|
394
|
+
loginType: 'fake-login-type',
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
parent: webex,
|
|
399
|
+
}
|
|
400
|
+
);
|
|
401
|
+
assert.equal(newMeeting.correlationId, uuid4);
|
|
402
|
+
assert.deepEqual(newMeeting.callStateForMetrics, {
|
|
403
|
+
correlationId: uuid4,
|
|
404
|
+
joinTrigger: 'fake-join-trigger',
|
|
405
|
+
loginType: 'fake-login-type',
|
|
406
|
+
});
|
|
378
407
|
});
|
|
379
408
|
|
|
380
409
|
describe('creates ReceiveSlot manager instance', () => {
|
|
@@ -851,6 +880,17 @@ describe('plugin-meetings', () => {
|
|
|
851
880
|
assert.calledOnce(meeting.startTranscription);
|
|
852
881
|
});
|
|
853
882
|
|
|
883
|
+
it('should take trigger from meeting joinTrigger if available', () => {
|
|
884
|
+
meeting.updateCallStateForMetrics({joinTrigger: 'fake-join-trigger'});
|
|
885
|
+
const join = meeting.join();
|
|
886
|
+
|
|
887
|
+
assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
|
|
888
|
+
name: 'client.call.initiated',
|
|
889
|
+
payload: {trigger: 'fake-join-trigger', isRoapCallEnabled: true},
|
|
890
|
+
options: {meetingId: meeting.id},
|
|
891
|
+
});
|
|
892
|
+
});
|
|
893
|
+
|
|
854
894
|
it('should not create new correlation ID on join immediately after create', async () => {
|
|
855
895
|
await meeting.join();
|
|
856
896
|
sinon.assert.notCalled(setCorrelationIdSpy);
|
|
@@ -1173,8 +1213,8 @@ describe('plugin-meetings', () => {
|
|
|
1173
1213
|
assert.exists(meeting.addMedia);
|
|
1174
1214
|
});
|
|
1175
1215
|
|
|
1176
|
-
it('should reject promise if meeting is not active', async () => {
|
|
1177
|
-
const result = await assert.isRejected(meeting.addMedia());
|
|
1216
|
+
it('should reject promise if meeting is not active and the meeting in lobby is not enabled', async () => {
|
|
1217
|
+
const result = await assert.isRejected(meeting.addMedia({allowMediaInLobby: false}));
|
|
1178
1218
|
|
|
1179
1219
|
assert.instanceOf(result, MeetingNotActiveError);
|
|
1180
1220
|
});
|
|
@@ -2583,8 +2623,12 @@ describe('plugin-meetings', () => {
|
|
|
2583
2623
|
setUnmuteAllowed: sinon.stub(),
|
|
2584
2624
|
setMuted: sinon.stub(),
|
|
2585
2625
|
setServerMuted: sinon.stub(),
|
|
2586
|
-
|
|
2587
|
-
|
|
2626
|
+
outputStream: {
|
|
2627
|
+
getTracks: () => {
|
|
2628
|
+
return [{
|
|
2629
|
+
id: 'fake mic'
|
|
2630
|
+
}];
|
|
2631
|
+
}
|
|
2588
2632
|
}
|
|
2589
2633
|
}
|
|
2590
2634
|
|
|
@@ -2795,10 +2839,10 @@ describe('plugin-meetings', () => {
|
|
|
2795
2839
|
assert.calledOnceWithExactly(roapMediaConnectionConstructorStub, mediaConnectionConfig,
|
|
2796
2840
|
{
|
|
2797
2841
|
localTracks: {
|
|
2798
|
-
audio: localStreams.audio?.
|
|
2799
|
-
video: localStreams.video?.
|
|
2800
|
-
screenShareVideo: localStreams.screenShareVideo?.
|
|
2801
|
-
screenShareAudio: localStreams.screenShareAudio?.
|
|
2842
|
+
audio: localStreams.audio?.outputStream?.getTracks()[0],
|
|
2843
|
+
video: localStreams.video?.outputStream?.getTracks()[0],
|
|
2844
|
+
screenShareVideo: localStreams.screenShareVideo?.outputStream?.getTracks()[0],
|
|
2845
|
+
screenShareAudio: localStreams.screenShareAudio?.outputStream?.getTracks()[0],
|
|
2802
2846
|
},
|
|
2803
2847
|
direction: {audio: direction.audio, video: direction.video, screenShareVideo: direction.screenShare},
|
|
2804
2848
|
remoteQualityLevel,
|
|
@@ -3073,7 +3117,7 @@ describe('plugin-meetings', () => {
|
|
|
3073
3117
|
assert.calledOnceWithExactly(meeting.sendSlotManager.getSlot(MediaType.AudioMain).publishStream, fakeMicrophoneStream);
|
|
3074
3118
|
} else {
|
|
3075
3119
|
assert.calledOnceWithExactly(fakeRoapMediaConnection.update, {
|
|
3076
|
-
localTracks: { audio: fakeMicrophoneStream.
|
|
3120
|
+
localTracks: { audio: fakeMicrophoneStream.outputStream.getTracks()[0], video: null, screenShareVideo: null, screenShareAudio: null },
|
|
3077
3121
|
direction: {
|
|
3078
3122
|
audio: expected.direction,
|
|
3079
3123
|
video: 'sendrecv',
|
|
@@ -3099,8 +3143,12 @@ describe('plugin-meetings', () => {
|
|
|
3099
3143
|
muted: false,
|
|
3100
3144
|
setUnmuteAllowed: sinon.stub(),
|
|
3101
3145
|
setMuted: sinon.stub(),
|
|
3102
|
-
|
|
3103
|
-
|
|
3146
|
+
outputStream: {
|
|
3147
|
+
getTracks: () => {
|
|
3148
|
+
return [{
|
|
3149
|
+
id: 'fake mic 2',
|
|
3150
|
+
}];
|
|
3151
|
+
}
|
|
3104
3152
|
}
|
|
3105
3153
|
}
|
|
3106
3154
|
|
|
@@ -3112,7 +3160,7 @@ describe('plugin-meetings', () => {
|
|
|
3112
3160
|
assert.calledOnceWithExactly(meeting.sendSlotManager.getSlot(MediaType.AudioMain).publishStream, fakeMicrophoneStream2);
|
|
3113
3161
|
} else {
|
|
3114
3162
|
assert.calledOnceWithExactly(fakeRoapMediaConnection.update, {
|
|
3115
|
-
localTracks: { audio: fakeMicrophoneStream2.
|
|
3163
|
+
localTracks: { audio: fakeMicrophoneStream2.outputStream.getTracks()[0], video: null, screenShareVideo: null, screenShareAudio: null },
|
|
3116
3164
|
direction: {
|
|
3117
3165
|
audio: expected.direction,
|
|
3118
3166
|
video: 'sendrecv',
|
|
@@ -3183,7 +3231,7 @@ describe('plugin-meetings', () => {
|
|
|
3183
3231
|
assert.equal(meeting.sendSlotManager.getSlot(MediaType.AudioMain).active, expectedDirection !== 'inactive');
|
|
3184
3232
|
} else {
|
|
3185
3233
|
assert.calledOnceWithExactly(fakeRoapMediaConnection.update, {
|
|
3186
|
-
localTracks: { audio: expectedStream?.
|
|
3234
|
+
localTracks: { audio: expectedStream?.outputStream.getTracks()[0] ?? null, video: null, screenShareVideo: null, screenShareAudio: null },
|
|
3187
3235
|
direction: {
|
|
3188
3236
|
audio: expectedDirection,
|
|
3189
3237
|
video: 'sendrecv',
|
|
@@ -3633,7 +3681,11 @@ describe('plugin-meetings', () => {
|
|
|
3633
3681
|
let sandbox;
|
|
3634
3682
|
|
|
3635
3683
|
const createFakeLocalStream = () => ({
|
|
3636
|
-
|
|
3684
|
+
outputStream: {
|
|
3685
|
+
getTracks: () => {
|
|
3686
|
+
return [{id: 'fake underlying track'}];
|
|
3687
|
+
}
|
|
3688
|
+
}
|
|
3637
3689
|
});
|
|
3638
3690
|
beforeEach(() => {
|
|
3639
3691
|
sandbox = sinon.createSandbox();
|
|
@@ -3716,10 +3768,10 @@ describe('plugin-meetings', () => {
|
|
|
3716
3768
|
meeting.mediaProperties.webrtcMediaConnection.update,
|
|
3717
3769
|
{
|
|
3718
3770
|
localTracks: {
|
|
3719
|
-
audio: meeting.mediaProperties.audioStream.
|
|
3720
|
-
video: meeting.mediaProperties.videoStream.
|
|
3721
|
-
screenShareVideo: meeting.mediaProperties.shareVideoStream.
|
|
3722
|
-
screenShareAudio: meeting.mediaProperties.shareVideoStream.
|
|
3771
|
+
audio: meeting.mediaProperties.audioStream.outputStream.getTracks()[0],
|
|
3772
|
+
video: meeting.mediaProperties.videoStream.outputStream.getTracks()[0],
|
|
3773
|
+
screenShareVideo: meeting.mediaProperties.shareVideoStream.outputStream.getTracks()[0],
|
|
3774
|
+
screenShareAudio: meeting.mediaProperties.shareVideoStream.outputStream.getTracks()[0],
|
|
3723
3775
|
},
|
|
3724
3776
|
direction: {
|
|
3725
3777
|
audio: 'inactive',
|
|
@@ -3748,7 +3800,13 @@ describe('plugin-meetings', () => {
|
|
|
3748
3800
|
meeting.mediaProperties.mediaDirection = mediaDirection;
|
|
3749
3801
|
meeting.mediaProperties.remoteVideoStream = sinon
|
|
3750
3802
|
.stub()
|
|
3751
|
-
.returns({
|
|
3803
|
+
.returns({
|
|
3804
|
+
outputStream: {
|
|
3805
|
+
getTracks: () => {
|
|
3806
|
+
id: 'some mock id'
|
|
3807
|
+
}
|
|
3808
|
+
}
|
|
3809
|
+
});
|
|
3752
3810
|
|
|
3753
3811
|
meeting.meetingRequest.changeVideoLayoutDebounced = sinon
|
|
3754
3812
|
.stub()
|
|
@@ -4573,7 +4631,7 @@ describe('plugin-meetings', () => {
|
|
|
4573
4631
|
};
|
|
4574
4632
|
const FAKE_MEETING_INFO_LOOKUP_URL = 'meetingLookupUrl';
|
|
4575
4633
|
const FAKE_PERMISSION_TOKEN = {someField: 'some value'};
|
|
4576
|
-
const
|
|
4634
|
+
const FAKE_TIMESTAMPS = {timeLeft: 13, expiryTime: 123456, currentTime: 123478};
|
|
4577
4635
|
|
|
4578
4636
|
beforeEach(() => {
|
|
4579
4637
|
meeting.locusId = 'locus-id';
|
|
@@ -4583,7 +4641,7 @@ describe('plugin-meetings', () => {
|
|
|
4583
4641
|
meeting.destination = 'meeting-destination';
|
|
4584
4642
|
meeting.destinationType = 'meeting-destination-type';
|
|
4585
4643
|
meeting.updateMeetingActions = sinon.stub().returns(undefined);
|
|
4586
|
-
|
|
4644
|
+
|
|
4587
4645
|
meeting.meetingInfoExtraParams = {
|
|
4588
4646
|
extraParam1: 'value1'
|
|
4589
4647
|
};
|
|
@@ -4604,6 +4662,50 @@ describe('plugin-meetings', () => {
|
|
|
4604
4662
|
});
|
|
4605
4663
|
|
|
4606
4664
|
it('calls meetingInfoProvider.fetchMeetingInfo() with the right params', async () => {
|
|
4665
|
+
meeting.getPermissionTokenExpiryInfo = sinon.stub().returns(FAKE_TIMESTAMPS);
|
|
4666
|
+
await meeting.refreshPermissionToken('fake reason');
|
|
4667
|
+
|
|
4668
|
+
assert.calledOnceWithExactly(
|
|
4669
|
+
meeting.attrs.meetingInfoProvider.fetchMeetingInfo,
|
|
4670
|
+
'meeting-destination',
|
|
4671
|
+
'meeting-destination-type',
|
|
4672
|
+
null,
|
|
4673
|
+
null,
|
|
4674
|
+
'fake-installed-org-id',
|
|
4675
|
+
'locus-id',
|
|
4676
|
+
{extraParam1: 'value1', permissionToken: FAKE_PERMISSION_TOKEN},
|
|
4677
|
+
{meetingId: meeting.id, sendCAevents: true}
|
|
4678
|
+
);
|
|
4679
|
+
assert.deepEqual(meeting.meetingInfo, {
|
|
4680
|
+
...FAKE_MEETING_INFO,
|
|
4681
|
+
meetingLookupUrl: FAKE_MEETING_INFO_LOOKUP_URL
|
|
4682
|
+
});
|
|
4683
|
+
assert.equal(meeting.meetingInfoFailureReason, MEETING_INFO_FAILURE_REASON.NONE);
|
|
4684
|
+
assert.equal(meeting.requiredCaptcha, null);
|
|
4685
|
+
assert.equal(meeting.passwordStatus, PASSWORD_STATUS.NOT_REQUIRED);
|
|
4686
|
+
|
|
4687
|
+
assert.calledWith(
|
|
4688
|
+
TriggerProxy.trigger,
|
|
4689
|
+
meeting,
|
|
4690
|
+
{file: 'meetings', function: 'fetchMeetingInfo'},
|
|
4691
|
+
'meeting:meetingInfoAvailable'
|
|
4692
|
+
);
|
|
4693
|
+
assert.calledWith(meeting.updateMeetingActions);
|
|
4694
|
+
|
|
4695
|
+
assert.calledWith(
|
|
4696
|
+
Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH, {
|
|
4697
|
+
correlationId: meeting.correlationId,
|
|
4698
|
+
timeLeft: FAKE_TIMESTAMPS.timeLeft,
|
|
4699
|
+
expiryTime: FAKE_TIMESTAMPS.expiryTime,
|
|
4700
|
+
currentTime: FAKE_TIMESTAMPS.currentTime,
|
|
4701
|
+
reason: 'fake reason',
|
|
4702
|
+
destinationType: 'meeting-destination-type',
|
|
4703
|
+
}
|
|
4704
|
+
);
|
|
4705
|
+
});
|
|
4706
|
+
|
|
4707
|
+
it('calls meetingInfoProvider.fetchMeetingInfo() with the right params when getPermissionTokenExpiryInfo returns undefined', async () => {
|
|
4708
|
+
meeting.getPermissionTokenExpiryInfo = sinon.stub().returns(undefined);
|
|
4607
4709
|
await meeting.refreshPermissionToken('fake reason');
|
|
4608
4710
|
|
|
4609
4711
|
assert.calledOnceWithExactly(
|
|
@@ -4636,7 +4738,9 @@ describe('plugin-meetings', () => {
|
|
|
4636
4738
|
assert.calledWith(
|
|
4637
4739
|
Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH, {
|
|
4638
4740
|
correlationId: meeting.correlationId,
|
|
4639
|
-
timeLeft:
|
|
4741
|
+
timeLeft: undefined,
|
|
4742
|
+
expiryTime: undefined,
|
|
4743
|
+
currentTime: undefined,
|
|
4640
4744
|
reason: 'fake reason',
|
|
4641
4745
|
destinationType: 'meeting-destination-type',
|
|
4642
4746
|
}
|
|
@@ -4644,6 +4748,7 @@ describe('plugin-meetings', () => {
|
|
|
4644
4748
|
});
|
|
4645
4749
|
|
|
4646
4750
|
it('calls meetingInfoProvider.fetchMeetingInfo() with the right params when we are starting an instant space meeting', async () => {
|
|
4751
|
+
meeting.getPermissionTokenExpiryInfo = sinon.stub().returns(FAKE_TIMESTAMPS);
|
|
4647
4752
|
meeting.destination = 'some-convo-url';
|
|
4648
4753
|
meeting.destinationType = 'CONVERSATION_URL';
|
|
4649
4754
|
meeting.config.experimental = {enableAdhocMeetings: true};
|
|
@@ -4685,7 +4790,9 @@ describe('plugin-meetings', () => {
|
|
|
4685
4790
|
assert.calledWith(
|
|
4686
4791
|
Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH, {
|
|
4687
4792
|
correlationId: meeting.correlationId,
|
|
4688
|
-
timeLeft:
|
|
4793
|
+
timeLeft: FAKE_TIMESTAMPS.timeLeft,
|
|
4794
|
+
expiryTime: FAKE_TIMESTAMPS.expiryTime,
|
|
4795
|
+
currentTime: FAKE_TIMESTAMPS.currentTime,
|
|
4689
4796
|
reason: 'some reason',
|
|
4690
4797
|
destinationType: 'MEETING_LINK',
|
|
4691
4798
|
}
|
|
@@ -5178,6 +5285,31 @@ describe('plugin-meetings', () => {
|
|
|
5178
5285
|
}
|
|
5179
5286
|
});
|
|
5180
5287
|
});
|
|
5288
|
+
|
|
5289
|
+
describe('#setCorrelationId', () => {
|
|
5290
|
+
it('should set the correlationId and return undefined', () => {
|
|
5291
|
+
assert.equal(meeting.correlationId, correlationId);
|
|
5292
|
+
assert.deepEqual(meeting.callStateForMetrics, {correlationId});
|
|
5293
|
+
meeting.setCorrelationId(uuid1);
|
|
5294
|
+
assert.equal(meeting.correlationId, uuid1);
|
|
5295
|
+
assert.deepEqual(meeting.callStateForMetrics, {correlationId: uuid1});
|
|
5296
|
+
});
|
|
5297
|
+
});
|
|
5298
|
+
|
|
5299
|
+
describe('#updateCallStateForMetrics', () => {
|
|
5300
|
+
it('should update the callState, overriding existing values', () => {
|
|
5301
|
+
assert.deepEqual(meeting.callStateForMetrics, {correlationId});
|
|
5302
|
+
meeting.updateCallStateForMetrics({correlationId: uuid1, joinTrigger: 'jt', loginType: 'lt'});
|
|
5303
|
+
assert.deepEqual(meeting.callStateForMetrics, {correlationId: uuid1, joinTrigger: 'jt', loginType: 'lt'});
|
|
5304
|
+
});
|
|
5305
|
+
|
|
5306
|
+
it('should update the callState, keeping non-supplied values', () => {
|
|
5307
|
+
assert.deepEqual(meeting.callStateForMetrics, {correlationId});
|
|
5308
|
+
meeting.updateCallStateForMetrics({joinTrigger: 'jt', loginType: 'lt'});
|
|
5309
|
+
assert.deepEqual(meeting.callStateForMetrics, {correlationId, joinTrigger: 'jt', loginType: 'lt'});
|
|
5310
|
+
});
|
|
5311
|
+
});
|
|
5312
|
+
|
|
5181
5313
|
describe('Local tracks publishing', () => {
|
|
5182
5314
|
let audioStream;
|
|
5183
5315
|
let videoStream;
|
|
@@ -5577,6 +5709,16 @@ describe('plugin-meetings', () => {
|
|
|
5577
5709
|
});
|
|
5578
5710
|
});
|
|
5579
5711
|
|
|
5712
|
+
it('should reconnect successfully if reconnectionManager.cleanUp is called before reconnection attempt', async () => {
|
|
5713
|
+
meeting.reconnectionManager.cleanUp();
|
|
5714
|
+
|
|
5715
|
+
try {
|
|
5716
|
+
await meeting.reconnect();
|
|
5717
|
+
} catch (err) {
|
|
5718
|
+
assert.fail('reconnect should not error after clean up');
|
|
5719
|
+
}
|
|
5720
|
+
})
|
|
5721
|
+
|
|
5580
5722
|
it('should trigger reconnection success and send CA metric', async () => {
|
|
5581
5723
|
await meeting.reconnect();
|
|
5582
5724
|
|
|
@@ -5662,7 +5804,7 @@ describe('plugin-meetings', () => {
|
|
|
5662
5804
|
it('should stop remote tracks, and trigger a media:stopped event when the remote tracks are stopped', async () => {
|
|
5663
5805
|
await meeting.closeRemoteStreams();
|
|
5664
5806
|
|
|
5665
|
-
assert.equal(TriggerProxy.trigger.callCount,
|
|
5807
|
+
assert.equal(TriggerProxy.trigger.callCount, 5);
|
|
5666
5808
|
assert.calledWith(
|
|
5667
5809
|
TriggerProxy.trigger,
|
|
5668
5810
|
sinon.match.instanceOf(Meeting),
|
|
@@ -7249,12 +7391,18 @@ describe('plugin-meetings', () => {
|
|
|
7249
7391
|
it('sets correctly when policy data is present in token', () => {
|
|
7250
7392
|
assert.notOk(meeting.selfUserPolicies);
|
|
7251
7393
|
|
|
7252
|
-
const
|
|
7394
|
+
const testUrl = 'https://example.com';
|
|
7395
|
+
|
|
7396
|
+
const policyData = {permission: {
|
|
7397
|
+
userPolicies: {a: true},
|
|
7398
|
+
enforceVBGImagesURL: testUrl
|
|
7399
|
+
}};
|
|
7253
7400
|
meeting.permissionTokenPayload = policyData;
|
|
7254
7401
|
|
|
7255
7402
|
meeting.setSelfUserPolicies();
|
|
7256
7403
|
|
|
7257
7404
|
assert.deepEqual(meeting.selfUserPolicies, policyData.permission.userPolicies);
|
|
7405
|
+
assert.equal(meeting.enforceVBGImagesURL, testUrl);
|
|
7258
7406
|
});
|
|
7259
7407
|
|
|
7260
7408
|
it('handles missing permission data', () => {
|
|
@@ -7522,14 +7670,6 @@ describe('plugin-meetings', () => {
|
|
|
7522
7670
|
});
|
|
7523
7671
|
});
|
|
7524
7672
|
|
|
7525
|
-
describe('#setCorrelationId', () => {
|
|
7526
|
-
it('should set the correlationId and return undefined', () => {
|
|
7527
|
-
assert.ok(meeting.correlationId);
|
|
7528
|
-
meeting.setCorrelationId(uuid1);
|
|
7529
|
-
assert.equal(meeting.correlationId, uuid1);
|
|
7530
|
-
});
|
|
7531
|
-
});
|
|
7532
|
-
|
|
7533
7673
|
describe('#setUpLocusInfoAssignHostListener', () => {
|
|
7534
7674
|
let locusInfoOnSpy;
|
|
7535
7675
|
let inMeetingActionsSetSpy;
|
|
@@ -7958,6 +8098,60 @@ describe('plugin-meetings', () => {
|
|
|
7958
8098
|
}
|
|
7959
8099
|
);
|
|
7960
8100
|
|
|
8101
|
+
forEach(
|
|
8102
|
+
[
|
|
8103
|
+
// policies supported and enforce is true
|
|
8104
|
+
{
|
|
8105
|
+
meetingInfo: {video: {}},
|
|
8106
|
+
selfUserPolicies: {
|
|
8107
|
+
[SELF_POLICY.ENFORCE_VIRTUAL_BACKGROUND]: true,
|
|
8108
|
+
},
|
|
8109
|
+
expectedActions: {
|
|
8110
|
+
enforceVirtualBackground: true,
|
|
8111
|
+
},
|
|
8112
|
+
},
|
|
8113
|
+
// policies supported and enforce is false
|
|
8114
|
+
{
|
|
8115
|
+
meetingInfo: {video: {}},
|
|
8116
|
+
selfUserPolicies: {
|
|
8117
|
+
[SELF_POLICY.ENFORCE_VIRTUAL_BACKGROUND]: false,
|
|
8118
|
+
},
|
|
8119
|
+
expectedActions: {
|
|
8120
|
+
enforceVirtualBackground: false,
|
|
8121
|
+
},
|
|
8122
|
+
},
|
|
8123
|
+
// policies not supported but enforce is true
|
|
8124
|
+
{
|
|
8125
|
+
meetingInfo: undefined,
|
|
8126
|
+
selfUserPolicies: {
|
|
8127
|
+
[SELF_POLICY.ENFORCE_VIRTUAL_BACKGROUND]: true,
|
|
8128
|
+
},
|
|
8129
|
+
expectedActions: {
|
|
8130
|
+
enforceVirtualBackground: false,
|
|
8131
|
+
},
|
|
8132
|
+
},
|
|
8133
|
+
],
|
|
8134
|
+
({meetingInfo, selfUserPolicies, expectedActions}) => {
|
|
8135
|
+
it(`expectedActions are ${JSON.stringify(
|
|
8136
|
+
expectedActions
|
|
8137
|
+
)} when policies are ${JSON.stringify(
|
|
8138
|
+
selfUserPolicies
|
|
8139
|
+
)} and meetingInfo is ${JSON.stringify(meetingInfo)}`, () => {
|
|
8140
|
+
meeting.meetingInfo = meetingInfo;
|
|
8141
|
+
meeting.selfUserPolicies = selfUserPolicies;
|
|
8142
|
+
|
|
8143
|
+
meeting.updateMeetingActions();
|
|
8144
|
+
|
|
8145
|
+
assert.deepEqual(
|
|
8146
|
+
{
|
|
8147
|
+
enforceVirtualBackground: meeting.inMeetingActions.enforceVirtualBackground,
|
|
8148
|
+
},
|
|
8149
|
+
expectedActions
|
|
8150
|
+
);
|
|
8151
|
+
});
|
|
8152
|
+
}
|
|
8153
|
+
);
|
|
8154
|
+
|
|
7961
8155
|
it('canUseVoip is disabled when the required policies are missing', () => {
|
|
7962
8156
|
meeting.userDisplayHints = [DISPLAY_HINTS.VOIP_IS_ENABLED];
|
|
7963
8157
|
meeting.selfUserPolicies = {};
|
|
@@ -10365,7 +10559,7 @@ describe('plugin-meetings', () => {
|
|
|
10365
10559
|
});
|
|
10366
10560
|
});
|
|
10367
10561
|
|
|
10368
|
-
describe('#
|
|
10562
|
+
describe('#getPermissionTokenExpiryInfo', () => {
|
|
10369
10563
|
let now;
|
|
10370
10564
|
let clock;
|
|
10371
10565
|
|
|
@@ -10381,63 +10575,65 @@ describe('plugin-meetings', () => {
|
|
|
10381
10575
|
})
|
|
10382
10576
|
|
|
10383
10577
|
it('should return undefined if exp is undefined', () => {
|
|
10384
|
-
assert.equal(meeting.
|
|
10578
|
+
assert.equal(meeting.getPermissionTokenExpiryInfo(), undefined)
|
|
10385
10579
|
});
|
|
10386
10580
|
|
|
10387
10581
|
it('should return the expected positive exp', () => {
|
|
10388
10582
|
// set permission token as now + 1 sec
|
|
10389
|
-
|
|
10390
|
-
|
|
10583
|
+
const expiryTime = now + 1000;
|
|
10584
|
+
meeting.permissionTokenPayload = {exp: (expiryTime).toString()};
|
|
10585
|
+
assert.deepEqual(meeting.getPermissionTokenExpiryInfo(), {timeLeft: 1, expiryTime: Number(expiryTime), currentTime: now});
|
|
10391
10586
|
});
|
|
10392
10587
|
|
|
10393
10588
|
it('should return the expected negative exp', () => {
|
|
10394
10589
|
// set permission token as now - 1 sec
|
|
10395
|
-
|
|
10396
|
-
|
|
10590
|
+
const expiryTime = now - 1000;
|
|
10591
|
+
meeting.permissionTokenPayload = {exp: (expiryTime).toString()};
|
|
10592
|
+
assert.deepEqual(meeting.getPermissionTokenExpiryInfo(), {timeLeft: -1, expiryTime: Number(expiryTime), currentTime: now});
|
|
10397
10593
|
});
|
|
10398
10594
|
});
|
|
10399
10595
|
|
|
10400
10596
|
describe('#checkAndRefreshPermissionToken', () => {
|
|
10401
10597
|
it('should not fire refreshPermissionToken if permissionToken is not defined', async() => {
|
|
10402
|
-
meeting.
|
|
10598
|
+
meeting.getPermissionTokenExpiryInfo = sinon.stub().returns(undefined)
|
|
10403
10599
|
meeting.refreshPermissionToken = sinon.stub().returns(Promise.resolve('test return value'));
|
|
10404
10600
|
|
|
10405
10601
|
const returnValue = await meeting.checkAndRefreshPermissionToken(10, 'ttl-join');
|
|
10406
10602
|
|
|
10407
|
-
assert.calledOnce(meeting.
|
|
10603
|
+
assert.calledOnce(meeting.getPermissionTokenExpiryInfo);
|
|
10408
10604
|
assert.notCalled(meeting.refreshPermissionToken);
|
|
10409
10605
|
assert.equal(returnValue, undefined);
|
|
10410
10606
|
});
|
|
10411
10607
|
|
|
10412
10608
|
it('should fire refreshPermissionToken if time left is below 10sec', async() => {
|
|
10413
|
-
meeting.
|
|
10609
|
+
meeting.getPermissionTokenExpiryInfo = sinon.stub().returns({timeLeft: 9, expiryTime: 122132, currentTime: Date.now()})
|
|
10414
10610
|
meeting.refreshPermissionToken = sinon.stub().returns(Promise.resolve('test return value'));
|
|
10415
10611
|
|
|
10416
10612
|
const returnValue = await meeting.checkAndRefreshPermissionToken(10, 'ttl-join');
|
|
10417
10613
|
|
|
10418
|
-
assert.calledOnce(meeting.
|
|
10614
|
+
assert.calledOnce(meeting.getPermissionTokenExpiryInfo);
|
|
10419
10615
|
assert.calledOnceWithExactly(meeting.refreshPermissionToken, 'ttl-join');
|
|
10420
10616
|
assert.equal(returnValue, 'test return value');
|
|
10421
10617
|
});
|
|
10422
10618
|
|
|
10423
10619
|
it('should fire refreshPermissionToken if time left is equal 10sec', async () => {
|
|
10424
|
-
meeting.
|
|
10620
|
+
meeting.getPermissionTokenExpiryInfo = sinon.stub().returns({timeLeft: 10, expiryTime: 122132, currentTime: Date.now()})
|
|
10425
10621
|
meeting.refreshPermissionToken = sinon.stub().returns(Promise.resolve('test return value'));
|
|
10426
10622
|
|
|
10427
10623
|
const returnValue = await meeting.checkAndRefreshPermissionToken(10, 'ttl-join');
|
|
10428
10624
|
|
|
10429
|
-
assert.calledOnce(meeting.
|
|
10625
|
+
assert.calledOnce(meeting.getPermissionTokenExpiryInfo);
|
|
10430
10626
|
assert.calledOnceWithExactly(meeting.refreshPermissionToken, 'ttl-join');
|
|
10431
10627
|
assert.equal(returnValue, 'test return value');
|
|
10432
10628
|
});
|
|
10433
10629
|
|
|
10434
10630
|
it('should not fire refreshPermissionToken if time left is higher than 10sec', async () => {
|
|
10435
|
-
meeting.
|
|
10631
|
+
meeting.getPermissionTokenExpiryInfo = sinon.stub().returns({timeLeft: 11, expiryTime: 122132, currentTime: Date.now()})
|
|
10436
10632
|
meeting.refreshPermissionToken = sinon.stub().returns(Promise.resolve('test return value'));
|
|
10437
10633
|
|
|
10438
10634
|
const returnValue = await meeting.checkAndRefreshPermissionToken(10, 'ttl-join');
|
|
10439
10635
|
|
|
10440
|
-
assert.calledOnce(meeting.
|
|
10636
|
+
assert.calledOnce(meeting.getPermissionTokenExpiryInfo);
|
|
10441
10637
|
assert.notCalled(meeting.refreshPermissionToken);
|
|
10442
10638
|
assert.equal(returnValue, undefined);
|
|
10443
10639
|
});
|
|
@@ -637,6 +637,29 @@ describe('plugin-meetings', () => {
|
|
|
637
637
|
|
|
638
638
|
const FAKE_USE_RANDOM_DELAY = true;
|
|
639
639
|
const correlationId = 'my-correlationId';
|
|
640
|
+
const callStateForMetrics = {
|
|
641
|
+
correlationId: 'my-correlationId2',
|
|
642
|
+
joinTrigger: 'my-join-trigger',
|
|
643
|
+
loginType: 'my-login-type',
|
|
644
|
+
};
|
|
645
|
+
|
|
646
|
+
it('should call setCallStateForMetrics on any pre-existing meeting', async () => {
|
|
647
|
+
const fakeMeeting = {setCallStateForMetrics: sinon.mock()};
|
|
648
|
+
webex.meetings.meetingCollection.getByKey = sinon.stub().returns(fakeMeeting);
|
|
649
|
+
await webex.meetings.create(
|
|
650
|
+
test1,
|
|
651
|
+
test2,
|
|
652
|
+
FAKE_USE_RANDOM_DELAY,
|
|
653
|
+
{},
|
|
654
|
+
correlationId,
|
|
655
|
+
true,
|
|
656
|
+
callStateForMetrics
|
|
657
|
+
);
|
|
658
|
+
assert.calledOnceWithExactly(fakeMeeting.setCallStateForMetrics, {
|
|
659
|
+
...callStateForMetrics,
|
|
660
|
+
correlationId,
|
|
661
|
+
});
|
|
662
|
+
});
|
|
640
663
|
|
|
641
664
|
const checkCallCreateMeeting = async (createParameters, createMeetingParameters) => {
|
|
642
665
|
const create = webex.meetings.create(...createParameters);
|
|
@@ -648,23 +671,37 @@ describe('plugin-meetings', () => {
|
|
|
648
671
|
};
|
|
649
672
|
|
|
650
673
|
it('calls createMeeting and returns its promise', async () => {
|
|
651
|
-
checkCallCreateMeeting(
|
|
674
|
+
await checkCallCreateMeeting(
|
|
652
675
|
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true],
|
|
653
|
-
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true]
|
|
676
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, true]
|
|
654
677
|
);
|
|
655
678
|
});
|
|
656
679
|
|
|
657
680
|
it('calls createMeeting when failOnMissingMeetinginfo is undefined and returns its promise', async () => {
|
|
658
|
-
checkCallCreateMeeting(
|
|
681
|
+
await checkCallCreateMeeting(
|
|
659
682
|
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, undefined],
|
|
660
|
-
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false]
|
|
683
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, false]
|
|
661
684
|
);
|
|
662
685
|
});
|
|
663
686
|
|
|
664
687
|
it('calls createMeeting when failOnMissingMeetinginfo is false and returns its promise', async () => {
|
|
665
|
-
checkCallCreateMeeting(
|
|
688
|
+
await checkCallCreateMeeting(
|
|
666
689
|
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false],
|
|
667
|
-
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false]
|
|
690
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, false]
|
|
691
|
+
);
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
it('calls createMeeting with callStateForMetrics and returns its promise', async () => {
|
|
695
|
+
await checkCallCreateMeeting(
|
|
696
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, undefined, true, callStateForMetrics],
|
|
697
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, callStateForMetrics, true]
|
|
698
|
+
);
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
it('calls createMeeting with callStateForMetrics overwritten with correlationId and returns its promise', async () => {
|
|
702
|
+
await checkCallCreateMeeting(
|
|
703
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true, callStateForMetrics],
|
|
704
|
+
[test1, test2, FAKE_USE_RANDOM_DELAY, {}, {...callStateForMetrics, correlationId}, true]
|
|
668
705
|
);
|
|
669
706
|
});
|
|
670
707
|
|
|
@@ -693,7 +730,8 @@ describe('plugin-meetings', () => {
|
|
|
693
730
|
test2,
|
|
694
731
|
FAKE_USE_RANDOM_DELAY,
|
|
695
732
|
FAKE_INFO_EXTRA_PARAMS,
|
|
696
|
-
correlationId
|
|
733
|
+
{correlationId},
|
|
734
|
+
false
|
|
697
735
|
);
|
|
698
736
|
});
|
|
699
737
|
|
|
@@ -1122,6 +1160,12 @@ describe('plugin-meetings', () => {
|
|
|
1122
1160
|
if (expectedMeetingData.correlationId) {
|
|
1123
1161
|
assert.equal(meeting.correlationId, expectedMeetingData.correlationId);
|
|
1124
1162
|
}
|
|
1163
|
+
if (expectedMeetingData.callStateForMetrics) {
|
|
1164
|
+
assert.deepEqual(
|
|
1165
|
+
meeting.callStateForMetrics,
|
|
1166
|
+
expectedMeetingData.callStateForMetrics
|
|
1167
|
+
);
|
|
1168
|
+
}
|
|
1125
1169
|
assert.equal(meeting.destination, destination);
|
|
1126
1170
|
assert.equal(meeting.destinationType, type);
|
|
1127
1171
|
assert.calledWith(
|
|
@@ -1390,7 +1434,7 @@ describe('plugin-meetings', () => {
|
|
|
1390
1434
|
'test type',
|
|
1391
1435
|
false,
|
|
1392
1436
|
{},
|
|
1393
|
-
'my-correlationId'
|
|
1437
|
+
{correlationId: 'my-correlationId'}
|
|
1394
1438
|
);
|
|
1395
1439
|
|
|
1396
1440
|
const expectedMeetingData = {
|
|
@@ -1406,6 +1450,38 @@ describe('plugin-meetings', () => {
|
|
|
1406
1450
|
true
|
|
1407
1451
|
);
|
|
1408
1452
|
});
|
|
1453
|
+
|
|
1454
|
+
it('creates meeting with the callStateForMetrics provided', async () => {
|
|
1455
|
+
const meeting = await webex.meetings.createMeeting(
|
|
1456
|
+
'test destination',
|
|
1457
|
+
'test type',
|
|
1458
|
+
false,
|
|
1459
|
+
{},
|
|
1460
|
+
{
|
|
1461
|
+
correlationId: 'my-correlationId',
|
|
1462
|
+
joinTrigger: 'my-join-trigger',
|
|
1463
|
+
loginType: 'my-login-type',
|
|
1464
|
+
}
|
|
1465
|
+
);
|
|
1466
|
+
|
|
1467
|
+
const expectedMeetingData = {
|
|
1468
|
+
correlationId: 'my-correlationId',
|
|
1469
|
+
callStateForMetrics: {
|
|
1470
|
+
correlationId: 'my-correlationId',
|
|
1471
|
+
joinTrigger: 'my-join-trigger',
|
|
1472
|
+
loginType: 'my-login-type',
|
|
1473
|
+
},
|
|
1474
|
+
};
|
|
1475
|
+
|
|
1476
|
+
checkCreateWithoutDelay(
|
|
1477
|
+
meeting,
|
|
1478
|
+
'test destination',
|
|
1479
|
+
'test type',
|
|
1480
|
+
{},
|
|
1481
|
+
expectedMeetingData,
|
|
1482
|
+
true
|
|
1483
|
+
);
|
|
1484
|
+
});
|
|
1409
1485
|
});
|
|
1410
1486
|
|
|
1411
1487
|
describe('rejected MeetingInfo.#fetchMeetingInfo', () => {
|