@webex/plugin-meetings 3.11.0 → 3.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aiEnableRequest/index.js +184 -0
- package/dist/aiEnableRequest/index.js.map +1 -0
- package/dist/aiEnableRequest/utils.js +36 -0
- package/dist/aiEnableRequest/utils.js.map +1 -0
- package/dist/annotation/index.js +14 -5
- package/dist/annotation/index.js.map +1 -1
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/config.js +5 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +28 -6
- package/dist/constants.js.map +1 -1
- package/dist/hashTree/constants.js +3 -1
- package/dist/hashTree/constants.js.map +1 -1
- package/dist/hashTree/hashTree.js +18 -0
- package/dist/hashTree/hashTree.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +709 -380
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/types.js +4 -2
- package/dist/hashTree/types.js.map +1 -1
- package/dist/hashTree/utils.js +10 -0
- package/dist/hashTree/utils.js.map +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/interceptors/constant.js +12 -0
- package/dist/interceptors/constant.js.map +1 -0
- package/dist/interceptors/dataChannelAuthToken.js +290 -0
- package/dist/interceptors/dataChannelAuthToken.js.map +1 -0
- package/dist/interceptors/index.js +7 -0
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interceptors/utils.js +27 -0
- package/dist/interceptors/utils.js.map +1 -0
- package/dist/interpretation/index.js +2 -2
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +5 -3
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +217 -79
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/selfUtils.js +1 -0
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/locus-info/types.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +57 -1
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/properties.js +4 -2
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +7 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +1082 -861
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +50 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +133 -3
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +100 -45
- package/dist/meetings/index.js.map +1 -1
- package/dist/member/index.js +10 -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/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +9 -60
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +11 -0
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/reachability/index.js +18 -10
- package/dist/reachability/index.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +0 -1
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/types/aiEnableRequest/index.d.ts +5 -0
- package/dist/types/aiEnableRequest/utils.d.ts +2 -0
- package/dist/types/config.d.ts +3 -0
- package/dist/types/constants.d.ts +23 -1
- package/dist/types/hashTree/constants.d.ts +1 -0
- package/dist/types/hashTree/hashTree.d.ts +7 -0
- package/dist/types/hashTree/hashTreeParser.d.ts +99 -14
- package/dist/types/hashTree/types.d.ts +3 -0
- package/dist/types/hashTree/utils.d.ts +6 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/interceptors/constant.d.ts +5 -0
- package/dist/types/interceptors/dataChannelAuthToken.d.ts +43 -0
- package/dist/types/interceptors/index.d.ts +2 -1
- package/dist/types/interceptors/utils.d.ts +1 -0
- package/dist/types/locus-info/index.d.ts +21 -2
- package/dist/types/locus-info/types.d.ts +1 -0
- package/dist/types/media/MediaConnectionAwaiter.d.ts +10 -1
- package/dist/types/media/properties.d.ts +2 -1
- package/dist/types/meeting/in-meeting-actions.d.ts +6 -0
- package/dist/types/meeting/index.d.ts +38 -6
- package/dist/types/meeting/request.d.ts +16 -1
- package/dist/types/meeting/request.type.d.ts +5 -0
- package/dist/types/meeting/util.d.ts +31 -0
- package/dist/types/meetings/index.d.ts +4 -2
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/member/util.d.ts +5 -0
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +0 -23
- package/dist/types/reactions/reactions.type.d.ts +1 -0
- package/dist/types/webinar/utils.d.ts +6 -0
- package/dist/webinar/index.js +260 -90
- package/dist/webinar/index.js.map +1 -1
- package/dist/webinar/utils.js +25 -0
- package/dist/webinar/utils.js.map +1 -0
- package/package.json +24 -23
- package/src/aiEnableRequest/README.md +84 -0
- package/src/aiEnableRequest/index.ts +170 -0
- package/src/aiEnableRequest/utils.ts +25 -0
- package/src/annotation/index.ts +27 -7
- package/src/config.ts +3 -0
- package/src/constants.ts +29 -1
- package/src/hashTree/constants.ts +1 -0
- package/src/hashTree/hashTree.ts +17 -0
- package/src/hashTree/hashTreeParser.ts +627 -249
- package/src/hashTree/types.ts +4 -0
- package/src/hashTree/utils.ts +9 -0
- package/src/index.ts +8 -1
- package/src/interceptors/constant.ts +6 -0
- package/src/interceptors/dataChannelAuthToken.ts +170 -0
- package/src/interceptors/index.ts +2 -1
- package/src/interceptors/utils.ts +16 -0
- package/src/interpretation/index.ts +2 -2
- package/src/locus-info/controlsUtils.ts +11 -0
- package/src/locus-info/index.ts +231 -61
- package/src/locus-info/selfUtils.ts +1 -0
- package/src/locus-info/types.ts +1 -0
- package/src/media/MediaConnectionAwaiter.ts +41 -1
- package/src/media/properties.ts +3 -1
- package/src/meeting/in-meeting-actions.ts +12 -0
- package/src/meeting/index.ts +205 -44
- package/src/meeting/request.ts +42 -0
- package/src/meeting/request.type.ts +6 -0
- package/src/meeting/util.ts +160 -2
- package/src/meetings/index.ts +135 -41
- package/src/member/index.ts +10 -0
- package/src/member/util.ts +12 -0
- package/src/metrics/constants.ts +1 -0
- package/src/multistream/mediaRequestManager.ts +4 -54
- package/src/multistream/remoteMediaManager.ts +13 -0
- package/src/reachability/index.ts +9 -0
- package/src/reactions/reactions.type.ts +1 -0
- package/src/reconnection-manager/index.ts +0 -1
- package/src/webinar/index.ts +162 -5
- package/src/webinar/utils.ts +16 -0
- package/test/unit/spec/aiEnableRequest/index.ts +981 -0
- package/test/unit/spec/aiEnableRequest/utils.ts +130 -0
- package/test/unit/spec/annotation/index.ts +69 -7
- package/test/unit/spec/hashTree/hashTree.ts +66 -0
- package/test/unit/spec/hashTree/hashTreeParser.ts +1869 -189
- package/test/unit/spec/interceptors/dataChannelAuthToken.ts +210 -0
- package/test/unit/spec/interceptors/utils.ts +75 -0
- package/test/unit/spec/locus-info/controlsUtils.js +29 -0
- package/test/unit/spec/locus-info/index.js +383 -46
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +41 -1
- package/test/unit/spec/media/properties.ts +12 -3
- package/test/unit/spec/meeting/in-meeting-actions.ts +8 -2
- package/test/unit/spec/meeting/index.js +716 -115
- package/test/unit/spec/meeting/request.js +70 -0
- package/test/unit/spec/meeting/utils.js +438 -26
- package/test/unit/spec/meetings/index.js +652 -31
- package/test/unit/spec/member/index.js +28 -4
- package/test/unit/spec/member/util.js +65 -27
- package/test/unit/spec/multistream/mediaRequestManager.ts +2 -85
- package/test/unit/spec/multistream/remoteMediaManager.ts +30 -0
- package/test/unit/spec/reachability/index.ts +23 -0
- package/test/unit/spec/reconnection-manager/index.js +4 -8
- package/test/unit/spec/webinar/index.ts +348 -36
- package/test/unit/spec/webinar/utils.ts +39 -0
|
@@ -18,6 +18,7 @@ describe('member', () => {
|
|
|
18
18
|
assert.exists(member.supportsBreakouts);
|
|
19
19
|
assert.exists(member.supportLiveAnnotation);
|
|
20
20
|
assert.exists(member.canReclaimHost);
|
|
21
|
+
assert.exists(member.canApproveAIEnablement);
|
|
21
22
|
});
|
|
22
23
|
|
|
23
24
|
describe('roles', () => {
|
|
@@ -47,17 +48,24 @@ describe('member', () => {
|
|
|
47
48
|
it('checks that processParticipant calls canReclaimHost', () => {
|
|
48
49
|
sinon.spy(MemberUtil, 'canReclaimHost');
|
|
49
50
|
member.processParticipant(participant);
|
|
50
|
-
|
|
51
|
+
|
|
51
52
|
assert.calledOnceWithExactly(MemberUtil.canReclaimHost, participant);
|
|
52
53
|
});
|
|
53
54
|
|
|
54
55
|
it('checks that processParticipant calls isPresenterAssignmentProhibited', () => {
|
|
55
56
|
sinon.spy(MemberUtil, 'isPresenterAssignmentProhibited');
|
|
56
57
|
member.processParticipant(participant);
|
|
57
|
-
|
|
58
|
+
|
|
58
59
|
assert.calledOnceWithExactly(MemberUtil.isPresenterAssignmentProhibited, participant);
|
|
59
60
|
});
|
|
60
|
-
|
|
61
|
+
|
|
62
|
+
it('checks that processParticipant calls canApproveAIEnablement', () => {
|
|
63
|
+
sinon.spy(MemberUtil, 'canApproveAIEnablement');
|
|
64
|
+
member.processParticipant(participant);
|
|
65
|
+
|
|
66
|
+
assert.calledOnceWithExactly(MemberUtil.canApproveAIEnablement, participant);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
61
69
|
|
|
62
70
|
describe('#processMember', () => {
|
|
63
71
|
it('checks that processMember calls isRemovable', () => {
|
|
@@ -80,5 +88,21 @@ describe('member', () => {
|
|
|
80
88
|
|
|
81
89
|
assert.calledOnceWithExactly(MemberUtil.extractMediaStatus, participant);
|
|
82
90
|
});
|
|
83
|
-
})
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
describe('canApproveAIEnablement integration', () => {
|
|
94
|
+
it('sets canApproveAIEnablement to the value returned by MemberUtil.canApproveAIEnablement', () => {
|
|
95
|
+
const testParticipant = {controls: {}, status: {}};
|
|
96
|
+
|
|
97
|
+
sinon.stub(MemberUtil, 'canApproveAIEnablement').returns(true);
|
|
98
|
+
const memberWithTrue = new Member(testParticipant);
|
|
99
|
+
assert.isTrue(memberWithTrue.canApproveAIEnablement);
|
|
100
|
+
|
|
101
|
+
MemberUtil.canApproveAIEnablement.restore();
|
|
102
|
+
|
|
103
|
+
sinon.stub(MemberUtil, 'canApproveAIEnablement').returns(false);
|
|
104
|
+
const memberWithFalse = new Member(testParticipant);
|
|
105
|
+
assert.isFalse(memberWithFalse.canApproveAIEnablement);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
84
108
|
});
|
|
@@ -82,6 +82,46 @@ describe('plugin-meetings', () => {
|
|
|
82
82
|
});
|
|
83
83
|
});
|
|
84
84
|
|
|
85
|
+
describe('MemberUtil.canApproveAIEnablement', () => {
|
|
86
|
+
it('returns false when there is no participant', () => {
|
|
87
|
+
assert.isFalse(MemberUtil.canApproveAIEnablement());
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('returns false when there is null participant', () => {
|
|
91
|
+
assert.isFalse(MemberUtil.canApproveAIEnablement(null));
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('returns true when attendeeRequestAiAssistantNotAllowed is false', () => {
|
|
95
|
+
const participant = {
|
|
96
|
+
attendeeRequestAiAssistantNotAllowed: false,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
assert.isTrue(MemberUtil.canApproveAIEnablement(participant));
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('returns false when attendeeRequestAiAssistantNotAllowed is true', () => {
|
|
103
|
+
const participant = {
|
|
104
|
+
attendeeRequestAiAssistantNotAllowed: true,
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
assert.isFalse(MemberUtil.canApproveAIEnablement(participant));
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('returns true when attendeeRequestAiAssistantNotAllowed is undefined', () => {
|
|
111
|
+
const participant = {
|
|
112
|
+
attendeeRequestAiAssistantNotAllowed: undefined,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
assert.isTrue(MemberUtil.canApproveAIEnablement(participant));
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('returns true when attendeeRequestAiAssistantNotAllowed is not present', () => {
|
|
119
|
+
const participant = {};
|
|
120
|
+
|
|
121
|
+
assert.isTrue(MemberUtil.canApproveAIEnablement(participant));
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
85
125
|
describe('MemberUtil.extractControlRoles', () => {
|
|
86
126
|
it('happy path extract control roles', () => {
|
|
87
127
|
const participant = {
|
|
@@ -377,7 +417,6 @@ describe('plugin-meetings', () => {
|
|
|
377
417
|
assert.isFalse(MemberUtil.isBrb(participant));
|
|
378
418
|
});
|
|
379
419
|
|
|
380
|
-
|
|
381
420
|
it('returns false when brb is not present', () => {
|
|
382
421
|
const participant = {
|
|
383
422
|
controls: {},
|
|
@@ -417,29 +456,28 @@ describe('plugin-meetings', () => {
|
|
|
417
456
|
});
|
|
418
457
|
});
|
|
419
458
|
|
|
420
|
-
describe('MemberUtil.isSupportsSingleUserAutoEndMeeting', () => {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
459
|
+
describe('MemberUtil.isSupportsSingleUserAutoEndMeeting', () => {
|
|
460
|
+
it('throws an error when there is no participant', () => {
|
|
461
|
+
assert.throws(() => {
|
|
462
|
+
MemberUtil.isSupportsSingleUserAutoEndMeeting();
|
|
463
|
+
}, 'Single user auto end meeting support could not be processed, participant is undefined.');
|
|
464
|
+
});
|
|
426
465
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
466
|
+
it('returns true when single user auto end meeting is supported', () => {
|
|
467
|
+
const participant = {
|
|
468
|
+
supportsSingleUserAutoEndMeeting: {},
|
|
469
|
+
};
|
|
470
|
+
assert.isTrue(MemberUtil.isSupportsSingleUserAutoEndMeeting(participant));
|
|
471
|
+
});
|
|
433
472
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
473
|
+
it('returns false when single user auto end meeting is not supported', () => {
|
|
474
|
+
const participant = {
|
|
475
|
+
doesNotSupportSingleUserAutoEndMeeting: {},
|
|
476
|
+
};
|
|
438
477
|
|
|
439
|
-
|
|
478
|
+
assert.isFalse(MemberUtil.isSupportsSingleUserAutoEndMeeting(participant));
|
|
479
|
+
});
|
|
440
480
|
});
|
|
441
|
-
});
|
|
442
|
-
|
|
443
481
|
|
|
444
482
|
describe('MemberUtil.isLiveAnnotationSupported', () => {
|
|
445
483
|
it('throws an error when there is no participant', () => {
|
|
@@ -585,7 +623,7 @@ describe('MemberUtil.isSupportsSingleUserAutoEndMeeting', () => {
|
|
|
585
623
|
describe('MemberUtil.isPresenterAssignmentProhibited', () => {
|
|
586
624
|
it('returns true when isPresenterAssignmentProhibited is true', () => {
|
|
587
625
|
const participant = {
|
|
588
|
-
presenterAssignmentNotAllowed: true
|
|
626
|
+
presenterAssignmentNotAllowed: true,
|
|
589
627
|
};
|
|
590
628
|
|
|
591
629
|
assert.isTrue(MemberUtil.isPresenterAssignmentProhibited(participant));
|
|
@@ -610,16 +648,16 @@ describe('MemberUtil.isSupportsSingleUserAutoEndMeeting', () => {
|
|
|
610
648
|
describe('extractMediaStatus', () => {
|
|
611
649
|
it('throws an error when there is no participant', () => {
|
|
612
650
|
assert.throws(() => {
|
|
613
|
-
MemberUtil.extractMediaStatus()
|
|
651
|
+
MemberUtil.extractMediaStatus();
|
|
614
652
|
}, 'Media status could not be extracted, participant is undefined.');
|
|
615
653
|
});
|
|
616
654
|
|
|
617
655
|
it('returns undefined media status when participant audio/video status is not present', () => {
|
|
618
656
|
const participant = {
|
|
619
|
-
status: {}
|
|
657
|
+
status: {},
|
|
620
658
|
};
|
|
621
659
|
|
|
622
|
-
const mediaStatus = MemberUtil.extractMediaStatus(participant)
|
|
660
|
+
const mediaStatus = MemberUtil.extractMediaStatus(participant);
|
|
623
661
|
|
|
624
662
|
assert.deepEqual(mediaStatus, {audio: undefined, video: undefined});
|
|
625
663
|
});
|
|
@@ -628,11 +666,11 @@ describe('extractMediaStatus', () => {
|
|
|
628
666
|
const participant = {
|
|
629
667
|
status: {
|
|
630
668
|
audioStatus: 'RECVONLY',
|
|
631
|
-
videoStatus: 'SENDRECV'
|
|
632
|
-
}
|
|
669
|
+
videoStatus: 'SENDRECV',
|
|
670
|
+
},
|
|
633
671
|
};
|
|
634
672
|
|
|
635
|
-
const mediaStatus = MemberUtil.extractMediaStatus(participant)
|
|
673
|
+
const mediaStatus = MemberUtil.extractMediaStatus(participant);
|
|
636
674
|
|
|
637
675
|
assert.deepEqual(mediaStatus, {audio: 'RECVONLY', video: 'SENDRECV'});
|
|
638
676
|
});
|
|
@@ -666,8 +666,8 @@ describe('MediaRequestManager', () => {
|
|
|
666
666
|
]);
|
|
667
667
|
});
|
|
668
668
|
|
|
669
|
-
it('
|
|
670
|
-
// send some requests and commit them
|
|
669
|
+
it('clears all the requests on reset()', () => {
|
|
670
|
+
// send some requests and commit them
|
|
671
671
|
addReceiverSelectedRequest(1500, fakeReceiveSlots[0], MAX_FS_1080p, false);
|
|
672
672
|
addReceiverSelectedRequest(1501, fakeReceiveSlots[1], MAX_FS_1080p, false);
|
|
673
673
|
addActiveSpeakerRequest(
|
|
@@ -722,95 +722,12 @@ describe('MediaRequestManager', () => {
|
|
|
722
722
|
},
|
|
723
723
|
]);
|
|
724
724
|
|
|
725
|
-
// check that when calling commit()
|
|
726
|
-
// all requests are not re-sent again (avoid duplicate requests)
|
|
727
|
-
mediaRequestManager.commit();
|
|
728
|
-
|
|
729
|
-
assert.notCalled(sendMediaRequestsCallback);
|
|
730
|
-
|
|
731
|
-
// now reset everything
|
|
732
|
-
mediaRequestManager.reset();
|
|
733
|
-
|
|
734
|
-
// calling commit now should not cause any requests to be sent out
|
|
735
|
-
mediaRequestManager.commit();
|
|
736
|
-
checkMediaRequestsSent([]);
|
|
737
|
-
});
|
|
738
|
-
|
|
739
|
-
it('makes sure to call requests correctly after reset was called and another request was added', () => {
|
|
740
|
-
addReceiverSelectedRequest(1500, fakeReceiveSlots[0], MAX_FS_1080p, false);
|
|
741
|
-
|
|
742
|
-
assert.notCalled(sendMediaRequestsCallback);
|
|
743
|
-
|
|
744
|
-
mediaRequestManager.commit();
|
|
745
|
-
checkMediaRequestsSent([
|
|
746
|
-
{
|
|
747
|
-
policy: 'receiver-selected',
|
|
748
|
-
csi: 1500,
|
|
749
|
-
receiveSlot: fakeWcmeSlots[0],
|
|
750
|
-
maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
|
|
751
|
-
maxFs: MAX_FS_1080p,
|
|
752
|
-
maxMbps: MAX_MBPS_1080p,
|
|
753
|
-
},
|
|
754
|
-
]);
|
|
755
|
-
|
|
756
725
|
// now reset everything
|
|
757
726
|
mediaRequestManager.reset();
|
|
758
727
|
|
|
759
728
|
// calling commit now should not cause any requests to be sent out
|
|
760
729
|
mediaRequestManager.commit();
|
|
761
730
|
checkMediaRequestsSent([]);
|
|
762
|
-
|
|
763
|
-
//add new request
|
|
764
|
-
addReceiverSelectedRequest(1501, fakeReceiveSlots[1], MAX_FS_1080p, false);
|
|
765
|
-
|
|
766
|
-
// commit
|
|
767
|
-
mediaRequestManager.commit();
|
|
768
|
-
|
|
769
|
-
// check the new request was sent
|
|
770
|
-
checkMediaRequestsSent([
|
|
771
|
-
{
|
|
772
|
-
policy: 'receiver-selected',
|
|
773
|
-
csi: 1501,
|
|
774
|
-
receiveSlot: fakeWcmeSlots[1],
|
|
775
|
-
maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
|
|
776
|
-
maxFs: MAX_FS_1080p,
|
|
777
|
-
maxMbps: MAX_MBPS_1080p,
|
|
778
|
-
},
|
|
779
|
-
]);
|
|
780
|
-
});
|
|
781
|
-
|
|
782
|
-
it('can send same media request after previous requests have been cleared', () => {
|
|
783
|
-
// add a request and commit
|
|
784
|
-
addReceiverSelectedRequest(1500, fakeReceiveSlots[0], MAX_FS_1080p, false);
|
|
785
|
-
mediaRequestManager.commit();
|
|
786
|
-
checkMediaRequestsSent([
|
|
787
|
-
{
|
|
788
|
-
policy: 'receiver-selected',
|
|
789
|
-
csi: 1500,
|
|
790
|
-
maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
|
|
791
|
-
receiveSlot: fakeWcmeSlots[0],
|
|
792
|
-
maxFs: MAX_FS_1080p,
|
|
793
|
-
maxMbps: MAX_MBPS_1080p,
|
|
794
|
-
},
|
|
795
|
-
]);
|
|
796
|
-
|
|
797
|
-
// clear previous requests
|
|
798
|
-
mediaRequestManager.clearPreviousRequests();
|
|
799
|
-
|
|
800
|
-
// commit same request
|
|
801
|
-
mediaRequestManager.commit();
|
|
802
|
-
|
|
803
|
-
// check the request was sent
|
|
804
|
-
checkMediaRequestsSent([
|
|
805
|
-
{
|
|
806
|
-
policy: 'receiver-selected',
|
|
807
|
-
csi: 1500,
|
|
808
|
-
maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_1080p,
|
|
809
|
-
receiveSlot: fakeWcmeSlots[0],
|
|
810
|
-
maxFs: MAX_FS_1080p,
|
|
811
|
-
maxMbps: MAX_MBPS_1080p,
|
|
812
|
-
},
|
|
813
|
-
]);
|
|
814
731
|
});
|
|
815
732
|
|
|
816
733
|
it('re-sends media requests after degradation preferences are set', () => {
|
|
@@ -965,6 +965,36 @@ describe('RemoteMediaManager', () => {
|
|
|
965
965
|
);
|
|
966
966
|
});
|
|
967
967
|
|
|
968
|
+
it('allocates 25 video slots for AllEqual25 layout', async () => {
|
|
969
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
970
|
+
config.video.layouts['AllEqual25'] = {
|
|
971
|
+
activeSpeakerVideoPaneGroups: [
|
|
972
|
+
{id: 'main', numPanes: 25, size: 'best', priority: 255},
|
|
973
|
+
],
|
|
974
|
+
};
|
|
975
|
+
config.video.initialLayoutId = 'AllEqual25';
|
|
976
|
+
|
|
977
|
+
let slotCount = 0;
|
|
978
|
+
fakeReceiveSlotManager.allocateSlot.callsFake((mediaType: MediaType) => {
|
|
979
|
+
if (mediaType === MediaType.VideoMain) {
|
|
980
|
+
slotCount += 1;
|
|
981
|
+
return Promise.resolve(new FakeSlot(mediaType, `fake video ${slotCount}`));
|
|
982
|
+
}
|
|
983
|
+
return Promise.resolve(fakeAudioSlot);
|
|
984
|
+
});
|
|
985
|
+
|
|
986
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
987
|
+
fakeReceiveSlotManager,
|
|
988
|
+
fakeMediaRequestManagers,
|
|
989
|
+
config
|
|
990
|
+
);
|
|
991
|
+
|
|
992
|
+
await remoteMediaManager.start();
|
|
993
|
+
|
|
994
|
+
assert.strictEqual(remoteMediaManager.getLayoutId(), 'AllEqual25');
|
|
995
|
+
assert.strictEqual(remoteMediaManager.slots.video.activeSpeaker.length, 25);
|
|
996
|
+
});
|
|
997
|
+
|
|
968
998
|
it('releases slots when switching to layout that requires less active speaker slots', async () => {
|
|
969
999
|
// start with "AllEqual" layout that needs just 9 video slots
|
|
970
1000
|
const config = cloneDeep(DefaultTestConfiguration);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {assert} from '@webex/test-helper-chai';
|
|
2
2
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
3
|
+
import { CapabilityState, WebCapabilities } from '@webex/web-capabilities';
|
|
3
4
|
import sinon from 'sinon';
|
|
4
5
|
import EventEmitter from 'events';
|
|
5
6
|
import testUtils from '../../../utils/testUtils';
|
|
@@ -8,6 +9,7 @@ import {ClusterNode} from '../../../../src/reachability/request';
|
|
|
8
9
|
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
9
10
|
import * as ClusterReachabilityModule from '@webex/plugin-meetings/src/reachability/clusterReachability';
|
|
10
11
|
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
12
|
+
import * as InternalMediaCore from '@webex/internal-media-core';
|
|
11
13
|
|
|
12
14
|
import {IP_VERSION} from '@webex/plugin-meetings/src/constants';
|
|
13
15
|
import { ReachabilityResultsForBackend } from '@webex/plugin-meetings/src/reachability/reachability.types';
|
|
@@ -466,11 +468,13 @@ describe('gatherReachability', () => {
|
|
|
466
468
|
let clock;
|
|
467
469
|
let clusterReachabilityCtorStub;
|
|
468
470
|
let mockClusterReachabilityInstances: Record<string, MockClusterReachability>;
|
|
471
|
+
let supportsRTCPeerConnectionStub;
|
|
469
472
|
|
|
470
473
|
beforeEach(async () => {
|
|
471
474
|
webex = new MockWebex();
|
|
472
475
|
|
|
473
476
|
sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
477
|
+
supportsRTCPeerConnectionStub = sinon.stub(WebCapabilities, 'supportsRTCPeerConnection').returns(CapabilityState.CAPABLE);
|
|
474
478
|
|
|
475
479
|
await webex.boundedStorage.put(
|
|
476
480
|
'Reachability',
|
|
@@ -545,6 +549,25 @@ describe('gatherReachability', () => {
|
|
|
545
549
|
await assert.isRejected(reachability.gatherReachability('test'), 'enableReachabilityChecks is disabled in config');
|
|
546
550
|
});
|
|
547
551
|
|
|
552
|
+
[CapabilityState.NOT_CAPABLE, CapabilityState.UNKNOWN].forEach((capabilityState) =>
|
|
553
|
+
it(`returns empty object if WebRTC API is not available (capabilityState=${capabilityState}`, async () => {
|
|
554
|
+
supportsRTCPeerConnectionStub.returns(capabilityState);
|
|
555
|
+
|
|
556
|
+
const reachability = new Reachability(webex);
|
|
557
|
+
|
|
558
|
+
const result = await reachability.gatherReachability('test');
|
|
559
|
+
|
|
560
|
+
assert.deepEqual(result, {});
|
|
561
|
+
|
|
562
|
+
// Verify that no new reachability result was stored - old results should remain unchanged
|
|
563
|
+
// This check is mainly to ensure that we don't put any "unreachable" results into storage
|
|
564
|
+
const storedResults = await webex.boundedStorage.get('Reachability', 'reachability.result');
|
|
565
|
+
assert.equal(storedResults, JSON.stringify({old: 'results'}));
|
|
566
|
+
|
|
567
|
+
assert.equal(await reachability.isWebexMediaBackendUnreachable(), false);
|
|
568
|
+
})
|
|
569
|
+
);
|
|
570
|
+
|
|
548
571
|
[
|
|
549
572
|
// ========================================================================
|
|
550
573
|
{
|
|
@@ -54,8 +54,8 @@ describe('plugin-meetings', () => {
|
|
|
54
54
|
webrtcMediaConnection: fakeMediaConnection,
|
|
55
55
|
},
|
|
56
56
|
mediaRequestManagers: {
|
|
57
|
-
audio: {commit: sinon.stub()
|
|
58
|
-
video: {commit: sinon.stub()
|
|
57
|
+
audio: {commit: sinon.stub()},
|
|
58
|
+
video: {commit: sinon.stub()},
|
|
59
59
|
},
|
|
60
60
|
roap: {
|
|
61
61
|
doTurnDiscovery: sinon.stub().resolves({
|
|
@@ -179,26 +179,22 @@ describe('plugin-meetings', () => {
|
|
|
179
179
|
});
|
|
180
180
|
});
|
|
181
181
|
|
|
182
|
-
it('does not
|
|
182
|
+
it('does not re-request media for non-multistream meetings', async () => {
|
|
183
183
|
fakeMeeting.isMultistream = false;
|
|
184
184
|
const rm = new ReconnectionManager(fakeMeeting);
|
|
185
185
|
|
|
186
186
|
await rm.reconnect();
|
|
187
187
|
|
|
188
|
-
assert.notCalled(fakeMeeting.mediaRequestManagers.audio.clearPreviousRequests);
|
|
189
|
-
assert.notCalled(fakeMeeting.mediaRequestManagers.video.clearPreviousRequests);
|
|
190
188
|
assert.notCalled(fakeMeeting.mediaRequestManagers.audio.commit);
|
|
191
189
|
assert.notCalled(fakeMeeting.mediaRequestManagers.video.commit);
|
|
192
190
|
});
|
|
193
191
|
|
|
194
|
-
it('does
|
|
192
|
+
it('does re-request media for multistream meetings', async () => {
|
|
195
193
|
fakeMeeting.isMultistream = true;
|
|
196
194
|
const rm = new ReconnectionManager(fakeMeeting);
|
|
197
195
|
|
|
198
196
|
await rm.reconnect();
|
|
199
197
|
|
|
200
|
-
assert.calledOnce(fakeMeeting.mediaRequestManagers.audio.clearPreviousRequests);
|
|
201
|
-
assert.calledOnce(fakeMeeting.mediaRequestManagers.video.clearPreviousRequests);
|
|
202
198
|
assert.calledOnce(fakeMeeting.mediaRequestManagers.audio.commit);
|
|
203
199
|
assert.calledOnce(fakeMeeting.mediaRequestManagers.video.commit);
|
|
204
200
|
});
|