@webex/plugin-meetings 3.8.1 → 3.9.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/README.md +26 -13
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/constants.js +32 -3
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +1 -0
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/types.js.map +1 -1
- package/dist/controls-options-manager/util.js +26 -0
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +11 -3
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +68 -84
- package/dist/locus-info/index.js.map +1 -1
- package/dist/media/index.js +2 -2
- package/dist/media/index.js.map +1 -1
- package/dist/meeting/brbState.js +17 -14
- package/dist/meeting/brbState.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +11 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +428 -253
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +19 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/{rtcMetrics/constants.js → meeting/type.js} +1 -5
- package/dist/meeting/type.js.map +1 -0
- package/dist/meeting/util.js +68 -2
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +35 -33
- package/dist/meetings/index.js.map +1 -1
- package/dist/members/index.js +11 -9
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +3 -3
- package/dist/members/request.js.map +1 -1
- package/dist/members/util.js +18 -6
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +1 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +1 -1
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +34 -5
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +42 -2
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +32 -2
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/reachability/index.js +5 -10
- package/dist/reachability/index.js.map +1 -1
- package/dist/types/constants.d.ts +28 -0
- package/dist/types/controls-options-manager/enums.d.ts +2 -1
- package/dist/types/controls-options-manager/types.d.ts +4 -1
- package/dist/types/locus-info/index.d.ts +0 -9
- package/dist/types/meeting/brbState.d.ts +0 -1
- package/dist/types/meeting/in-meeting-actions.d.ts +10 -0
- package/dist/types/meeting/index.d.ts +47 -19
- package/dist/types/meeting/request.d.ts +9 -1
- package/dist/types/meeting/request.type.d.ts +74 -0
- package/dist/types/meeting/type.d.ts +9 -0
- package/dist/types/meeting/util.d.ts +3 -0
- package/dist/types/members/index.d.ts +10 -7
- package/dist/types/members/request.d.ts +1 -1
- package/dist/types/members/util.d.ts +7 -3
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/multistream/remoteMedia.d.ts +20 -1
- package/dist/types/multistream/remoteMediaGroup.d.ts +11 -0
- package/dist/types/multistream/sendSlotManager.d.ts +16 -0
- package/dist/types/reachability/index.d.ts +2 -2
- package/dist/webinar/index.js +1 -1
- package/package.json +24 -25
- package/src/constants.ts +32 -2
- package/src/controls-options-manager/enums.ts +1 -0
- package/src/controls-options-manager/types.ts +6 -1
- package/src/controls-options-manager/util.ts +31 -0
- package/src/locus-info/controlsUtils.ts +15 -0
- package/src/locus-info/index.ts +88 -82
- package/src/media/index.ts +2 -2
- package/src/meeting/brbState.ts +13 -9
- package/src/meeting/in-meeting-actions.ts +21 -0
- package/src/meeting/index.ts +254 -71
- package/src/meeting/request.ts +16 -0
- package/src/meeting/request.type.ts +64 -0
- package/src/meeting/type.ts +9 -0
- package/src/meeting/util.ts +73 -2
- package/src/meetings/index.ts +3 -2
- package/src/members/index.ts +13 -10
- package/src/members/request.ts +2 -2
- package/src/members/util.ts +16 -4
- package/src/metrics/constants.ts +1 -0
- package/src/multistream/mediaRequestManager.ts +7 -7
- package/src/multistream/remoteMedia.ts +34 -4
- package/src/multistream/remoteMediaGroup.ts +37 -2
- package/src/multistream/sendSlotManager.ts +34 -2
- package/src/reachability/index.ts +5 -13
- package/test/unit/spec/controls-options-manager/util.js +58 -0
- package/test/unit/spec/locus-info/controlsUtils.js +52 -0
- package/test/unit/spec/locus-info/index.js +218 -82
- package/test/unit/spec/media/index.ts +107 -0
- package/test/unit/spec/meeting/brbState.ts +23 -4
- package/test/unit/spec/meeting/in-meeting-actions.ts +10 -0
- package/test/unit/spec/meeting/index.js +901 -84
- package/test/unit/spec/meeting/request.js +71 -0
- package/test/unit/spec/meeting/utils.js +122 -1
- package/test/unit/spec/meetings/index.js +2 -0
- package/test/unit/spec/members/index.js +68 -9
- package/test/unit/spec/members/request.js +2 -2
- package/test/unit/spec/members/utils.js +27 -7
- package/test/unit/spec/multistream/mediaRequestManager.ts +19 -6
- package/test/unit/spec/multistream/remoteMedia.ts +66 -2
- package/test/unit/spec/multistream/sendSlotManager.ts +59 -0
- package/test/unit/spec/reachability/index.ts +2 -6
- package/dist/annotation/annotation.types.d.ts +0 -42
- package/dist/annotation/constants.d.ts +0 -31
- package/dist/annotation/index.d.ts +0 -117
- package/dist/breakouts/breakout.d.ts +0 -8
- package/dist/breakouts/collection.d.ts +0 -5
- package/dist/breakouts/edit-lock-error.d.ts +0 -15
- package/dist/breakouts/events.d.ts +0 -8
- package/dist/breakouts/index.d.ts +0 -5
- package/dist/breakouts/request.d.ts +0 -22
- package/dist/breakouts/utils.d.ts +0 -15
- package/dist/common/browser-detection.d.ts +0 -9
- package/dist/common/collection.d.ts +0 -48
- package/dist/common/config.d.ts +0 -2
- package/dist/common/errors/captcha-error.d.ts +0 -15
- package/dist/common/errors/intent-to-join.d.ts +0 -16
- package/dist/common/errors/join-meeting.d.ts +0 -17
- package/dist/common/errors/media.d.ts +0 -15
- package/dist/common/errors/no-meeting-info.d.ts +0 -14
- package/dist/common/errors/parameter.d.ts +0 -15
- package/dist/common/errors/password-error.d.ts +0 -15
- package/dist/common/errors/permission.d.ts +0 -14
- package/dist/common/errors/reclaim-host-role-error.d.ts +0 -60
- package/dist/common/errors/reclaim-host-role-error.js +0 -158
- package/dist/common/errors/reclaim-host-role-error.js.map +0 -1
- package/dist/common/errors/reclaim-host-role-errors.d.ts +0 -60
- package/dist/common/errors/reconnection-in-progress.d.ts +0 -9
- package/dist/common/errors/reconnection-in-progress.js +0 -35
- package/dist/common/errors/reconnection-in-progress.js.map +0 -1
- package/dist/common/errors/reconnection.d.ts +0 -15
- package/dist/common/errors/stats.d.ts +0 -15
- package/dist/common/errors/webex-errors.d.ts +0 -81
- package/dist/common/errors/webex-meetings-error.d.ts +0 -20
- package/dist/common/events/events-scope.d.ts +0 -17
- package/dist/common/events/events.d.ts +0 -12
- package/dist/common/events/trigger-proxy.d.ts +0 -2
- package/dist/common/events/util.d.ts +0 -2
- package/dist/common/logs/logger-config.d.ts +0 -2
- package/dist/common/logs/logger-proxy.d.ts +0 -2
- package/dist/common/logs/request.d.ts +0 -34
- package/dist/common/queue.d.ts +0 -32
- package/dist/config.d.ts +0 -73
- package/dist/constants.d.ts +0 -952
- package/dist/controls-options-manager/constants.d.ts +0 -4
- package/dist/controls-options-manager/enums.d.ts +0 -5
- package/dist/controls-options-manager/index.d.ts +0 -120
- package/dist/controls-options-manager/types.d.ts +0 -43
- package/dist/controls-options-manager/util.d.ts +0 -7
- package/dist/index.d.ts +0 -4
- package/dist/interceptors/index.d.ts +0 -2
- package/dist/interceptors/locusRetry.d.ts +0 -27
- package/dist/interpretation/collection.d.ts +0 -5
- package/dist/interpretation/index.d.ts +0 -5
- package/dist/interpretation/siLanguage.d.ts +0 -5
- package/dist/locus-info/controlsUtils.d.ts +0 -2
- package/dist/locus-info/embeddedAppsUtils.d.ts +0 -2
- package/dist/locus-info/fullState.d.ts +0 -2
- package/dist/locus-info/hostUtils.d.ts +0 -2
- package/dist/locus-info/index.d.ts +0 -269
- package/dist/locus-info/infoUtils.d.ts +0 -2
- package/dist/locus-info/mediaSharesUtils.d.ts +0 -2
- package/dist/locus-info/parser.d.ts +0 -212
- package/dist/locus-info/selfUtils.d.ts +0 -2
- package/dist/media/index.d.ts +0 -32
- package/dist/media/properties.d.ts +0 -108
- package/dist/media/util.d.ts +0 -2
- package/dist/mediaQualityMetrics/config.d.ts +0 -233
- package/dist/mediaQualityMetrics/config.js +0 -513
- package/dist/mediaQualityMetrics/config.js.map +0 -1
- package/dist/meeting/effectsState.d.ts +0 -42
- package/dist/meeting/effectsState.js +0 -260
- package/dist/meeting/effectsState.js.map +0 -1
- package/dist/meeting/in-meeting-actions.d.ts +0 -79
- package/dist/meeting/index.d.ts +0 -1622
- package/dist/meeting/locusMediaRequest.d.ts +0 -74
- package/dist/meeting/muteState.d.ts +0 -116
- package/dist/meeting/request.d.ts +0 -257
- package/dist/meeting/request.type.d.ts +0 -11
- package/dist/meeting/state.d.ts +0 -9
- package/dist/meeting/util.d.ts +0 -2
- package/dist/meeting/voicea-meeting.d.ts +0 -16
- package/dist/meeting-info/collection.d.ts +0 -20
- package/dist/meeting-info/index.d.ts +0 -57
- package/dist/meeting-info/meeting-info-v2.d.ts +0 -93
- package/dist/meeting-info/request.d.ts +0 -22
- package/dist/meeting-info/util.d.ts +0 -2
- package/dist/meeting-info/utilv2.d.ts +0 -2
- package/dist/meetings/collection.d.ts +0 -23
- package/dist/meetings/index.d.ts +0 -296
- package/dist/meetings/meetings.types.d.ts +0 -4
- package/dist/meetings/request.d.ts +0 -27
- package/dist/meetings/util.d.ts +0 -18
- package/dist/member/index.d.ts +0 -148
- package/dist/member/member.types.d.ts +0 -11
- package/dist/member/member.types.js +0 -18
- package/dist/member/member.types.js.map +0 -1
- package/dist/member/types.d.ts +0 -32
- package/dist/member/util.d.ts +0 -2
- package/dist/members/collection.d.ts +0 -24
- package/dist/members/index.d.ts +0 -308
- package/dist/members/request.d.ts +0 -58
- package/dist/members/types.d.ts +0 -25
- package/dist/members/util.d.ts +0 -2
- package/dist/metrics/config.d.ts +0 -169
- package/dist/metrics/config.js +0 -289
- package/dist/metrics/config.js.map +0 -1
- package/dist/metrics/constants.d.ts +0 -59
- package/dist/metrics/index.d.ts +0 -152
- package/dist/multistream/mediaRequestManager.d.ts +0 -119
- package/dist/multistream/receiveSlot.d.ts +0 -68
- package/dist/multistream/receiveSlotManager.d.ts +0 -56
- package/dist/multistream/remoteMedia.d.ts +0 -72
- package/dist/multistream/remoteMediaGroup.d.ts +0 -49
- package/dist/multistream/remoteMediaManager.d.ts +0 -300
- package/dist/multistream/sendSlotManager.d.ts +0 -69
- package/dist/networkQualityMonitor/index.d.ts +0 -70
- package/dist/networkQualityMonitor/index.js +0 -226
- package/dist/networkQualityMonitor/index.js.map +0 -1
- package/dist/peer-connection-manager/index.d.ts +0 -6
- package/dist/peer-connection-manager/index.js +0 -671
- package/dist/peer-connection-manager/index.js.map +0 -1
- package/dist/peer-connection-manager/util.d.ts +0 -6
- package/dist/peer-connection-manager/util.js +0 -110
- package/dist/peer-connection-manager/util.js.map +0 -1
- package/dist/personal-meeting-room/index.d.ts +0 -47
- package/dist/personal-meeting-room/request.d.ts +0 -14
- package/dist/personal-meeting-room/util.d.ts +0 -2
- package/dist/reachability/clusterReachability.d.ts +0 -109
- package/dist/reachability/index.d.ts +0 -139
- package/dist/reachability/request.d.ts +0 -35
- package/dist/reachability/util.d.ts +0 -8
- package/dist/reactions/constants.d.ts +0 -3
- package/dist/reactions/reactions.d.ts +0 -4
- package/dist/reactions/reactions.type.d.ts +0 -32
- package/dist/reconnection-manager/index.d.ts +0 -112
- package/dist/recording-controller/enums.d.ts +0 -7
- package/dist/recording-controller/index.d.ts +0 -193
- package/dist/recording-controller/util.d.ts +0 -13
- package/dist/roap/collection.d.ts +0 -10
- package/dist/roap/collection.js +0 -63
- package/dist/roap/collection.js.map +0 -1
- package/dist/roap/handler.d.ts +0 -47
- package/dist/roap/handler.js +0 -279
- package/dist/roap/handler.js.map +0 -1
- package/dist/roap/index.d.ts +0 -116
- package/dist/roap/request.d.ts +0 -35
- package/dist/roap/state.d.ts +0 -9
- package/dist/roap/state.js +0 -127
- package/dist/roap/state.js.map +0 -1
- package/dist/roap/turnDiscovery.d.ts +0 -81
- package/dist/roap/util.d.ts +0 -2
- package/dist/roap/util.js +0 -76
- package/dist/roap/util.js.map +0 -1
- package/dist/rtcMetrics/constants.d.ts +0 -4
- package/dist/rtcMetrics/constants.js.map +0 -1
- package/dist/rtcMetrics/index.d.ts +0 -61
- package/dist/rtcMetrics/index.js +0 -197
- package/dist/rtcMetrics/index.js.map +0 -1
- package/dist/statsAnalyzer/global.d.ts +0 -118
- package/dist/statsAnalyzer/global.js +0 -127
- package/dist/statsAnalyzer/global.js.map +0 -1
- package/dist/statsAnalyzer/index.d.ts +0 -193
- package/dist/statsAnalyzer/index.js +0 -1019
- package/dist/statsAnalyzer/index.js.map +0 -1
- package/dist/statsAnalyzer/mqaUtil.d.ts +0 -22
- package/dist/statsAnalyzer/mqaUtil.js +0 -181
- package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
- package/dist/transcription/index.d.ts +0 -64
- package/dist/types/common/errors/reconnection-in-progress.d.ts +0 -9
- package/dist/types/mediaQualityMetrics/config.d.ts +0 -241
- package/dist/types/networkQualityMonitor/index.d.ts +0 -70
- package/dist/types/rtcMetrics/constants.d.ts +0 -4
- package/dist/types/rtcMetrics/index.d.ts +0 -71
- package/dist/types/statsAnalyzer/global.d.ts +0 -36
- package/dist/types/statsAnalyzer/index.d.ts +0 -217
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
- package/dist/webinar/collection.d.ts +0 -16
- package/dist/webinar/index.d.ts +0 -5
@@ -56,6 +56,7 @@ import * as MeetingRequestImport from '@webex/plugin-meetings/src/meeting/reques
|
|
56
56
|
import LocusInfo from '@webex/plugin-meetings/src/locus-info';
|
57
57
|
import MediaProperties from '@webex/plugin-meetings/src/media/properties';
|
58
58
|
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
59
|
+
import MembersUtil from '@webex/plugin-meetings/src/members/util';
|
59
60
|
import MeetingsUtil from '@webex/plugin-meetings/src/meetings/util';
|
60
61
|
import Media from '@webex/plugin-meetings/src/media/index';
|
61
62
|
import ReconnectionManager from '@webex/plugin-meetings/src/reconnection-manager';
|
@@ -244,6 +245,7 @@ describe('plugin-meetings', () => {
|
|
244
245
|
});
|
245
246
|
|
246
247
|
webex.internal.newMetrics.callDiagnosticMetrics.clearErrorCache = sinon.stub();
|
248
|
+
webex.internal.newMetrics.callDiagnosticMetrics.clearEventLimitsForCorrelationId = sinon.stub();
|
247
249
|
webex.internal.support.submitLogs = sinon.stub().returns(Promise.resolve());
|
248
250
|
webex.internal.services = {get: sinon.stub().returns('locus-url')};
|
249
251
|
webex.credentials.getOrgId = sinon.stub().returns('fake-org-id');
|
@@ -368,6 +370,35 @@ describe('plugin-meetings', () => {
|
|
368
370
|
assert.instanceOf(meeting.simultaneousInterpretation, SimultaneousInterpretation);
|
369
371
|
assert.instanceOf(meeting.webinar, Webinar);
|
370
372
|
});
|
373
|
+
|
374
|
+
it('should call the callback with the meeting that has id already set', () => {
|
375
|
+
let meetingIdFromCallback;
|
376
|
+
// check that the meeting id is already set correctly at the time when the callback is called
|
377
|
+
const meetingCreationCallback = sinon.stub().callsFake((meeting) => {
|
378
|
+
meetingIdFromCallback = meeting.id;
|
379
|
+
});
|
380
|
+
|
381
|
+
meeting = new Meeting(
|
382
|
+
{
|
383
|
+
userId: uuid1,
|
384
|
+
resource: uuid2,
|
385
|
+
deviceUrl: uuid3,
|
386
|
+
locus: {url: url1},
|
387
|
+
destination: testDestination,
|
388
|
+
destinationType: DESTINATION_TYPE.MEETING_ID,
|
389
|
+
correlationId,
|
390
|
+
selfId: uuid1,
|
391
|
+
},
|
392
|
+
{
|
393
|
+
parent: webex,
|
394
|
+
},
|
395
|
+
meetingCreationCallback
|
396
|
+
);
|
397
|
+
assert.exists(meeting.id);
|
398
|
+
assert.calledOnceWithExactly(meetingCreationCallback, meeting);
|
399
|
+
assert.equal(meeting.id, meetingIdFromCallback);
|
400
|
+
});
|
401
|
+
|
371
402
|
it('creates MediaRequestManager instances', () => {
|
372
403
|
assert.instanceOf(meeting.mediaRequestManagers.audio, MediaRequestManager);
|
373
404
|
assert.instanceOf(meeting.mediaRequestManagers.video, MediaRequestManager);
|
@@ -454,6 +485,18 @@ describe('plugin-meetings', () => {
|
|
454
485
|
});
|
455
486
|
});
|
456
487
|
|
488
|
+
it('pstnCorrelationId getter/setter should work correctly', () => {
|
489
|
+
const testPstnCorrelationId = uuid.v4();
|
490
|
+
|
491
|
+
meeting.pstnCorrelationId = testPstnCorrelationId;
|
492
|
+
assert.equal(meeting.pstnCorrelationId, testPstnCorrelationId);
|
493
|
+
assert.equal(meeting.callStateForMetrics.pstnCorrelationId, testPstnCorrelationId);
|
494
|
+
|
495
|
+
meeting.pstnCorrelationId = undefined;
|
496
|
+
assert.equal(meeting.pstnCorrelationId, undefined);
|
497
|
+
assert.equal(meeting.callStateForMetrics.pstnCorrelationId, undefined);
|
498
|
+
});
|
499
|
+
|
457
500
|
describe('creates ReceiveSlot manager instance', () => {
|
458
501
|
let mockReceiveSlotManagerCtor;
|
459
502
|
let providedCreateSlotCallback;
|
@@ -581,7 +624,6 @@ describe('plugin-meetings', () => {
|
|
581
624
|
assert.isFalse(meeting.isLocusCall());
|
582
625
|
});
|
583
626
|
});
|
584
|
-
|
585
627
|
describe('#invite', () => {
|
586
628
|
it('should have #invite', () => {
|
587
629
|
assert.exists(meeting.invite);
|
@@ -592,8 +634,6 @@ describe('plugin-meetings', () => {
|
|
592
634
|
it('should proxy members #addMember and return a promise', async () => {
|
593
635
|
const invite = meeting.invite(uuid1, false);
|
594
636
|
|
595
|
-
assert.exists(invite.then);
|
596
|
-
await invite;
|
597
637
|
assert.calledOnce(meeting.members.addMember);
|
598
638
|
assert.calledWith(meeting.members.addMember, uuid1, false);
|
599
639
|
});
|
@@ -614,20 +654,20 @@ describe('plugin-meetings', () => {
|
|
614
654
|
assert.calledWith(meeting.members.cancelPhoneInvite, uuid1);
|
615
655
|
});
|
616
656
|
});
|
617
|
-
describe('#
|
618
|
-
it('should have #
|
619
|
-
assert.exists(meeting.
|
657
|
+
describe('#cancelInviteByMemberId', () => {
|
658
|
+
it('should have #cancelInviteByMemberId', () => {
|
659
|
+
assert.exists(meeting.cancelInviteByMemberId);
|
620
660
|
});
|
621
661
|
beforeEach(() => {
|
622
|
-
meeting.members.
|
662
|
+
meeting.members.cancelInviteByMemberId = sinon.stub().returns(Promise.resolve(test1));
|
623
663
|
});
|
624
|
-
it('should proxy members #
|
625
|
-
const cancel = meeting.
|
664
|
+
it('should proxy members #cancelInviteByMemberId and return a promise', async () => {
|
665
|
+
const cancel = meeting.cancelInviteByMemberId({memberId: uuid1});
|
626
666
|
|
627
667
|
assert.exists(cancel.then);
|
628
668
|
await cancel;
|
629
|
-
assert.calledOnce(meeting.members.
|
630
|
-
assert.calledWith(meeting.members.
|
669
|
+
assert.calledOnce(meeting.members.cancelInviteByMemberId);
|
670
|
+
assert.calledWith(meeting.members.cancelInviteByMemberId, {memberId: uuid1});
|
631
671
|
});
|
632
672
|
});
|
633
673
|
describe('#admit', () => {
|
@@ -1208,8 +1248,73 @@ describe('plugin-meetings', () => {
|
|
1208
1248
|
reason: 'joinWithMedia failure',
|
1209
1249
|
});
|
1210
1250
|
});
|
1211
|
-
});
|
1212
1251
|
|
1252
|
+
it('should ignore sendVideo/receiveVideo when videoEnabled is false', async () => {
|
1253
|
+
await meeting.joinWithMedia({
|
1254
|
+
joinOptions,
|
1255
|
+
mediaOptions: {
|
1256
|
+
videoEnabled: false,
|
1257
|
+
sendVideo: true,
|
1258
|
+
receiveVideo: true,
|
1259
|
+
allowMediaInLobby: true,
|
1260
|
+
},
|
1261
|
+
});
|
1262
|
+
|
1263
|
+
assert.calledWithMatch(
|
1264
|
+
meeting.addMediaInternal,
|
1265
|
+
sinon.match.any,
|
1266
|
+
sinon.match.any,
|
1267
|
+
sinon.match.any,
|
1268
|
+
sinon.match.has('videoEnabled', false).and(sinon.match.has('allowMediaInLobby', true))
|
1269
|
+
);
|
1270
|
+
});
|
1271
|
+
|
1272
|
+
it('should ignore sendAudio/receiveAudio when audioEnabled is false', async () => {
|
1273
|
+
await meeting.joinWithMedia({
|
1274
|
+
joinOptions,
|
1275
|
+
mediaOptions: {
|
1276
|
+
audioEnabled: false,
|
1277
|
+
sendAudio: true,
|
1278
|
+
receiveAudio: false,
|
1279
|
+
allowMediaInLobby: true,
|
1280
|
+
},
|
1281
|
+
});
|
1282
|
+
|
1283
|
+
assert.calledWithMatch(
|
1284
|
+
meeting.addMediaInternal,
|
1285
|
+
sinon.match.any,
|
1286
|
+
sinon.match.any,
|
1287
|
+
sinon.match.any,
|
1288
|
+
sinon.match.has('audioEnabled', false).and(sinon.match.has('allowMediaInLobby', true))
|
1289
|
+
);
|
1290
|
+
});
|
1291
|
+
|
1292
|
+
it('should use provided send/receive values when videoEnabled/audioEnabled are true or not set', async () => {
|
1293
|
+
await meeting.joinWithMedia({
|
1294
|
+
joinOptions,
|
1295
|
+
mediaOptions: {
|
1296
|
+
sendVideo: true,
|
1297
|
+
receiveVideo: false,
|
1298
|
+
sendAudio: false,
|
1299
|
+
receiveAudio: true,
|
1300
|
+
allowMediaInLobby: true,
|
1301
|
+
},
|
1302
|
+
});
|
1303
|
+
|
1304
|
+
assert.calledWith(
|
1305
|
+
meeting.addMediaInternal,
|
1306
|
+
sinon.match.any,
|
1307
|
+
sinon.match.any,
|
1308
|
+
sinon.match.any,
|
1309
|
+
sinon.match({
|
1310
|
+
sendVideo: true,
|
1311
|
+
receiveVideo: false,
|
1312
|
+
sendAudio: false,
|
1313
|
+
receiveAudio: true,
|
1314
|
+
})
|
1315
|
+
);
|
1316
|
+
});
|
1317
|
+
});
|
1213
1318
|
describe('#isTranscriptionSupported', () => {
|
1214
1319
|
it('should return false if the feature is not supported for the meeting', () => {
|
1215
1320
|
meeting.locusInfo.controls = {transcribe: {caption: false}};
|
@@ -1223,6 +1328,44 @@ describe('plugin-meetings', () => {
|
|
1223
1328
|
});
|
1224
1329
|
});
|
1225
1330
|
|
1331
|
+
describe('#update spoken language', () => {
|
1332
|
+
beforeEach(() => {
|
1333
|
+
webex.internal.voicea.onSpokenLanguageUpdate = sinon.stub();
|
1334
|
+
meeting.transcription = {languageOptions: {currentSpokenLanguage: 'en'}};
|
1335
|
+
});
|
1336
|
+
afterEach(() => {
|
1337
|
+
// Restore the original methods after each test
|
1338
|
+
sinon.restore();
|
1339
|
+
});
|
1340
|
+
it('should call voicea.onSpokenLanguageUpdate when joined', async () => {
|
1341
|
+
meeting.joinedWith = {state: 'JOINED'};
|
1342
|
+
await meeting.locusInfo.emitScoped(
|
1343
|
+
{function: 'test', file: 'test'},
|
1344
|
+
LOCUSINFO.EVENTS.CONTROLS_MEETING_TRANSCRIPTION_SPOKEN_LANGUAGE_UPDATED,
|
1345
|
+
{spokenLanguage: 'fr'}
|
1346
|
+
);
|
1347
|
+
assert.calledWith(webex.internal.voicea.onSpokenLanguageUpdate, 'fr', meeting.id);
|
1348
|
+
assert.equal(meeting.transcription.languageOptions.currentSpokenLanguage, 'fr');
|
1349
|
+
assert.calledWith(
|
1350
|
+
TriggerProxy.trigger,
|
1351
|
+
meeting,
|
1352
|
+
{file: 'meeting/index', function: 'setupLocusControlsListener'},
|
1353
|
+
EVENT_TRIGGERS.MEETING_TRANSCRIPTION_SPOKEN_LANGUAGE_UPDATED
|
1354
|
+
);
|
1355
|
+
});
|
1356
|
+
|
1357
|
+
it('should also call voicea.onSpokenLanguageUpdate when not joined', async () => {
|
1358
|
+
meeting.joinedWith = {state: 'NOT_JOINED'};
|
1359
|
+
await meeting.locusInfo.emitScoped(
|
1360
|
+
{function: 'test', file: 'test'},
|
1361
|
+
LOCUSINFO.EVENTS.CONTROLS_MEETING_TRANSCRIPTION_SPOKEN_LANGUAGE_UPDATED,
|
1362
|
+
{spokenLanguage: 'de'}
|
1363
|
+
);
|
1364
|
+
assert.calledWith(webex.internal.voicea.onSpokenLanguageUpdate, 'de');
|
1365
|
+
assert.equal(meeting.transcription.languageOptions.currentSpokenLanguage, 'de');
|
1366
|
+
});
|
1367
|
+
});
|
1368
|
+
|
1226
1369
|
describe('#startTranscription', () => {
|
1227
1370
|
beforeEach(() => {
|
1228
1371
|
webex.internal.voicea.on = sinon.stub();
|
@@ -1846,21 +1989,25 @@ describe('plugin-meetings', () => {
|
|
1846
1989
|
});
|
1847
1990
|
});
|
1848
1991
|
|
1849
|
-
it('should
|
1992
|
+
it('should handle join failure', async () => {
|
1850
1993
|
MeetingUtil.isPinOrGuest = sinon.stub().returns(false);
|
1994
|
+
webex.internal.newMetrics.submitClientEvent = sinon.stub();
|
1995
|
+
|
1851
1996
|
await meeting.join().catch(() => {
|
1852
|
-
assert.
|
1853
|
-
|
1854
|
-
|
1855
|
-
);
|
1856
|
-
assert.
|
1857
|
-
webex.internal.newMetrics.submitClientEvent
|
1997
|
+
assert.calledOnce(MeetingUtil.joinMeeting);
|
1998
|
+
|
1999
|
+
// Assert that client.locus.join.response error event is not sent from this function, it is now emitted from MeetingUtil.joinMeeting
|
2000
|
+
assert.calledOnce(webex.internal.newMetrics.submitClientEvent);
|
2001
|
+
assert.calledWithMatch(
|
2002
|
+
webex.internal.newMetrics.submitClientEvent,
|
1858
2003
|
{
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
2004
|
+
name: 'client.call.initiated',
|
2005
|
+
payload: {
|
2006
|
+
trigger: 'user-interaction',
|
2007
|
+
isRoapCallEnabled: true,
|
2008
|
+
pstnAudioType: undefined
|
2009
|
+
},
|
2010
|
+
options: {meetingId: meeting.id},
|
1864
2011
|
}
|
1865
2012
|
);
|
1866
2013
|
});
|
@@ -2061,14 +2208,12 @@ describe('plugin-meetings', () => {
|
|
2061
2208
|
};
|
2062
2209
|
meeting.mediaProperties.setMediaDirection = sinon.stub().returns(true);
|
2063
2210
|
meeting.mediaProperties.waitForMediaConnectionConnected = sinon.stub().resolves();
|
2064
|
-
meeting.mediaProperties.getCurrentConnectionInfo = sinon
|
2065
|
-
|
2066
|
-
|
2067
|
-
|
2068
|
-
|
2069
|
-
|
2070
|
-
ipVersion: 'IPv6',
|
2071
|
-
});
|
2211
|
+
meeting.mediaProperties.getCurrentConnectionInfo = sinon.stub().resolves({
|
2212
|
+
connectionType: 'udp',
|
2213
|
+
selectedCandidatePairChanges: 2,
|
2214
|
+
numTransports: 1,
|
2215
|
+
ipVersion: 'IPv6',
|
2216
|
+
});
|
2072
2217
|
meeting.audio = muteStateStub;
|
2073
2218
|
meeting.video = muteStateStub;
|
2074
2219
|
sinon.stub(Media, 'createMediaConnection').returns(fakeMediaConnection);
|
@@ -2187,8 +2332,9 @@ describe('plugin-meetings', () => {
|
|
2187
2332
|
someReachabilityMetric1: 'some value1',
|
2188
2333
|
someReachabilityMetric2: 'some value2',
|
2189
2334
|
selectedCandidatePairChanges: 2,
|
2190
|
-
|
2191
|
-
|
2335
|
+
subnet_reachable: null,
|
2336
|
+
selected_cluster: null,
|
2337
|
+
selected_subnet: null,
|
2192
2338
|
numTransports: 1,
|
2193
2339
|
iceCandidatesCount: 0,
|
2194
2340
|
}
|
@@ -2235,8 +2381,9 @@ describe('plugin-meetings', () => {
|
|
2235
2381
|
signalingState: 'unknown',
|
2236
2382
|
connectionState: 'unknown',
|
2237
2383
|
iceConnectionState: 'unknown',
|
2238
|
-
|
2239
|
-
|
2384
|
+
subnet_reachable: null,
|
2385
|
+
selected_cluster: null,
|
2386
|
+
selected_subnet: null,
|
2240
2387
|
})
|
2241
2388
|
);
|
2242
2389
|
|
@@ -2302,8 +2449,9 @@ describe('plugin-meetings', () => {
|
|
2302
2449
|
selectedCandidatePairChanges: 2,
|
2303
2450
|
numTransports: 1,
|
2304
2451
|
iceCandidatesCount: 0,
|
2305
|
-
|
2306
|
-
|
2452
|
+
subnet_reachable: null,
|
2453
|
+
selected_cluster: null,
|
2454
|
+
selected_subnet: null,
|
2307
2455
|
}
|
2308
2456
|
);
|
2309
2457
|
});
|
@@ -2361,8 +2509,9 @@ describe('plugin-meetings', () => {
|
|
2361
2509
|
signalingState: 'have-local-offer',
|
2362
2510
|
connectionState: 'connecting',
|
2363
2511
|
iceConnectionState: 'checking',
|
2364
|
-
|
2365
|
-
|
2512
|
+
subnet_reachable: null,
|
2513
|
+
selected_cluster: null,
|
2514
|
+
selected_subnet: null,
|
2366
2515
|
})
|
2367
2516
|
);
|
2368
2517
|
|
@@ -2420,8 +2569,9 @@ describe('plugin-meetings', () => {
|
|
2420
2569
|
signalingState: 'have-local-offer',
|
2421
2570
|
connectionState: 'connecting',
|
2422
2571
|
iceConnectionState: 'checking',
|
2423
|
-
|
2424
|
-
|
2572
|
+
subnet_reachable: null,
|
2573
|
+
selected_cluster: null,
|
2574
|
+
selected_subnet: null,
|
2425
2575
|
})
|
2426
2576
|
);
|
2427
2577
|
|
@@ -2943,8 +3093,9 @@ describe('plugin-meetings', () => {
|
|
2943
3093
|
selectedCandidatePairChanges: 2,
|
2944
3094
|
numTransports: 1,
|
2945
3095
|
iceCandidatesCount: 0,
|
2946
|
-
|
2947
|
-
|
3096
|
+
subnet_reachable: null,
|
3097
|
+
selected_cluster: null,
|
3098
|
+
selected_subnet: null,
|
2948
3099
|
},
|
2949
3100
|
]);
|
2950
3101
|
|
@@ -3151,8 +3302,9 @@ describe('plugin-meetings', () => {
|
|
3151
3302
|
retriedWithTurnServer: true,
|
3152
3303
|
isJoinWithMediaRetry: false,
|
3153
3304
|
iceCandidatesCount: 0,
|
3154
|
-
|
3155
|
-
|
3305
|
+
subnet_reachable: null,
|
3306
|
+
selected_cluster: null,
|
3307
|
+
selected_subnet: null,
|
3156
3308
|
},
|
3157
3309
|
]);
|
3158
3310
|
meeting.roap.doTurnDiscovery;
|
@@ -3286,8 +3438,8 @@ describe('plugin-meetings', () => {
|
|
3286
3438
|
meeting.mediaConnections = [
|
3287
3439
|
{
|
3288
3440
|
mediaAgentCluster: 'some.cluster',
|
3289
|
-
}
|
3290
|
-
]
|
3441
|
+
},
|
3442
|
+
];
|
3291
3443
|
meeting.iceCandidatesCount = 3;
|
3292
3444
|
meeting.iceCandidateErrors.set('701_error', 3);
|
3293
3445
|
meeting.iceCandidateErrors.set('701_turn_host_lookup_received_error', 1);
|
@@ -3315,8 +3467,9 @@ describe('plugin-meetings', () => {
|
|
3315
3467
|
iceCandidatesCount: 3,
|
3316
3468
|
'701_error': 3,
|
3317
3469
|
'701_turn_host_lookup_received_error': 1,
|
3318
|
-
|
3319
|
-
|
3470
|
+
subnet_reachable: null,
|
3471
|
+
selected_cluster: 'some.cluster',
|
3472
|
+
selected_subnet: null,
|
3320
3473
|
}
|
3321
3474
|
);
|
3322
3475
|
|
@@ -3379,8 +3532,9 @@ describe('plugin-meetings', () => {
|
|
3379
3532
|
iceConnectionState: 'unknown',
|
3380
3533
|
selectedCandidatePairChanges: 2,
|
3381
3534
|
numTransports: 1,
|
3382
|
-
|
3383
|
-
|
3535
|
+
subnet_reachable: null,
|
3536
|
+
selected_cluster: null,
|
3537
|
+
selected_subnet: null,
|
3384
3538
|
iceCandidatesCount: 0,
|
3385
3539
|
}
|
3386
3540
|
);
|
@@ -3442,8 +3596,9 @@ describe('plugin-meetings', () => {
|
|
3442
3596
|
numTransports: 1,
|
3443
3597
|
'701_error': 2,
|
3444
3598
|
'701_turn_host_lookup_received_error': 1,
|
3445
|
-
|
3446
|
-
|
3599
|
+
subnet_reachable: null,
|
3600
|
+
selected_cluster: null,
|
3601
|
+
selected_subnet: null,
|
3447
3602
|
iceCandidatesCount: 0,
|
3448
3603
|
}
|
3449
3604
|
);
|
@@ -3451,7 +3606,7 @@ describe('plugin-meetings', () => {
|
|
3451
3606
|
assert.isOk(errorThrown);
|
3452
3607
|
});
|
3453
3608
|
|
3454
|
-
it('should send
|
3609
|
+
it('should send subnet reachablity metrics if media connection success', async () => {
|
3455
3610
|
meeting.roap.doTurnDiscovery = sinon.stub().returns({
|
3456
3611
|
turnServerInfo: undefined,
|
3457
3612
|
turnDiscoverySkippedReason: undefined,
|
@@ -3465,6 +3620,12 @@ describe('plugin-meetings', () => {
|
|
3465
3620
|
stopReachability: sinon.stub(),
|
3466
3621
|
isSubnetReachable: sinon.stub().returns(false),
|
3467
3622
|
};
|
3623
|
+
meeting.mediaServerIp = '1.2.3.4';
|
3624
|
+
meeting.mediaConnections = [
|
3625
|
+
{
|
3626
|
+
mediaAgentCluster: 'some.cluster',
|
3627
|
+
},
|
3628
|
+
];
|
3468
3629
|
|
3469
3630
|
const forceRtcMetricsSend = sinon.stub().resolves();
|
3470
3631
|
const closeMediaConnectionStub = sinon.stub();
|
@@ -3492,12 +3653,13 @@ describe('plugin-meetings', () => {
|
|
3492
3653
|
isJoinWithMediaRetry: false,
|
3493
3654
|
iceCandidatesCount: 0,
|
3494
3655
|
reachability_public_udp_success: 5,
|
3495
|
-
|
3496
|
-
|
3656
|
+
subnet_reachable: false,
|
3657
|
+
selected_cluster: 'some.cluster',
|
3658
|
+
selected_subnet: '1.X.X.X',
|
3497
3659
|
});
|
3498
3660
|
});
|
3499
3661
|
|
3500
|
-
it('should send
|
3662
|
+
it('should send subnet reachablity metrics if media connection fails', async () => {
|
3501
3663
|
let errorThrown = undefined;
|
3502
3664
|
|
3503
3665
|
meeting.roap.doTurnDiscovery = sinon.stub().returns({
|
@@ -3513,6 +3675,12 @@ describe('plugin-meetings', () => {
|
|
3513
3675
|
stopReachability: sinon.stub(),
|
3514
3676
|
isSubnetReachable: sinon.stub().returns(true),
|
3515
3677
|
};
|
3678
|
+
meeting.mediaServerIp = '1.2.3.4';
|
3679
|
+
meeting.mediaConnections = [
|
3680
|
+
{
|
3681
|
+
mediaAgentCluster: 'some.cluster',
|
3682
|
+
},
|
3683
|
+
];
|
3516
3684
|
|
3517
3685
|
const forceRtcMetricsSend = sinon.stub().resolves();
|
3518
3686
|
const closeMediaConnectionStub = sinon.stub();
|
@@ -3554,8 +3722,9 @@ describe('plugin-meetings', () => {
|
|
3554
3722
|
selectedCandidatePairChanges: 2,
|
3555
3723
|
numTransports: 1,
|
3556
3724
|
reachability_public_udp_success: 5,
|
3557
|
-
|
3558
|
-
|
3725
|
+
subnet_reachable: true,
|
3726
|
+
selected_cluster: 'some.cluster',
|
3727
|
+
selected_subnet: '1.X.X.X',
|
3559
3728
|
iceCandidatesCount: 0,
|
3560
3729
|
}
|
3561
3730
|
);
|
@@ -4152,7 +4321,7 @@ describe('plugin-meetings', () => {
|
|
4152
4321
|
meeting.deviceUrl = 'device url';
|
4153
4322
|
meeting.selfId = 'self id';
|
4154
4323
|
meeting.brbState = createBrbState(meeting, false);
|
4155
|
-
meeting.brbState
|
4324
|
+
sinon.stub(meeting.brbState, 'enable').resolves();
|
4156
4325
|
});
|
4157
4326
|
|
4158
4327
|
afterEach(() => {
|
@@ -4216,6 +4385,17 @@ describe('plugin-meetings', () => {
|
|
4216
4385
|
|
4217
4386
|
assert.notCalled(meeting.audio.handleServerRemoteMuteUpdate);
|
4218
4387
|
});
|
4388
|
+
|
4389
|
+
it('should reject when brb enable fails', async () => {
|
4390
|
+
meeting.brbState.enable.restore();
|
4391
|
+
|
4392
|
+
const error = new Error();
|
4393
|
+
meeting.meetingRequest.setBrb = sinon.stub().rejects(error);
|
4394
|
+
|
4395
|
+
await expect(meeting.beRightBack(true)).to.be.rejectedWith(error);
|
4396
|
+
|
4397
|
+
assert.isFalse(meeting.brbState.state.syncToServerInProgress);
|
4398
|
+
});
|
4219
4399
|
});
|
4220
4400
|
});
|
4221
4401
|
|
@@ -6362,12 +6542,17 @@ describe('plugin-meetings', () => {
|
|
6362
6542
|
const DIAL_IN_URL = meeting.dialInUrl;
|
6363
6543
|
|
6364
6544
|
assert.calledWith(meeting.meetingRequest.dialIn, {
|
6365
|
-
correlationId: meeting.
|
6545
|
+
correlationId: meeting.pstnCorrelationId,
|
6366
6546
|
dialInUrl: DIAL_IN_URL,
|
6367
6547
|
locusUrl: meeting.locusUrl,
|
6368
6548
|
clientUrl: meeting.deviceUrl,
|
6369
6549
|
});
|
6370
6550
|
assert.notCalled(meeting.meetingRequest.dialOut);
|
6551
|
+
|
6552
|
+
// Verify pstnCorrelationId was set
|
6553
|
+
assert.exists(meeting.pstnCorrelationId);
|
6554
|
+
assert.notEqual(meeting.pstnCorrelationId, meeting.correlationId);
|
6555
|
+
const firstPstnCorrelationId = meeting.pstnCorrelationId
|
6371
6556
|
|
6372
6557
|
meeting.meetingRequest.dialIn.resetHistory();
|
6373
6558
|
|
@@ -6375,12 +6560,18 @@ describe('plugin-meetings', () => {
|
|
6375
6560
|
await meeting.usePhoneAudio();
|
6376
6561
|
|
6377
6562
|
assert.calledWith(meeting.meetingRequest.dialIn, {
|
6378
|
-
correlationId: meeting.
|
6563
|
+
correlationId: meeting.pstnCorrelationId,
|
6379
6564
|
dialInUrl: DIAL_IN_URL,
|
6380
6565
|
locusUrl: meeting.locusUrl,
|
6381
6566
|
clientUrl: meeting.deviceUrl,
|
6382
6567
|
});
|
6383
6568
|
assert.notCalled(meeting.meetingRequest.dialOut);
|
6569
|
+
// A new PSTN correlationId should be generated for the second attempt
|
6570
|
+
assert.notEqual(
|
6571
|
+
meeting.pstnCorrelationId,
|
6572
|
+
firstPstnCorrelationId,
|
6573
|
+
'pstnCorrelationId should be regenerated on each dial-in attempt'
|
6574
|
+
);
|
6384
6575
|
});
|
6385
6576
|
|
6386
6577
|
it('given a phone number, triggers dial-out, delegating request to meetingRequest correctly', async () => {
|
@@ -6390,7 +6581,7 @@ describe('plugin-meetings', () => {
|
|
6390
6581
|
const DIAL_OUT_URL = meeting.dialOutUrl;
|
6391
6582
|
|
6392
6583
|
assert.calledWith(meeting.meetingRequest.dialOut, {
|
6393
|
-
correlationId: meeting.
|
6584
|
+
correlationId: meeting.pstnCorrelationId,
|
6394
6585
|
dialOutUrl: DIAL_OUT_URL,
|
6395
6586
|
locusUrl: meeting.locusUrl,
|
6396
6587
|
clientUrl: meeting.deviceUrl,
|
@@ -6398,49 +6589,126 @@ describe('plugin-meetings', () => {
|
|
6398
6589
|
});
|
6399
6590
|
assert.notCalled(meeting.meetingRequest.dialIn);
|
6400
6591
|
|
6592
|
+
// Verify pstnCorrelationId was set
|
6593
|
+
assert.exists(meeting.pstnCorrelationId);
|
6594
|
+
assert.notEqual(meeting.pstnCorrelationId, meeting.correlationId);
|
6595
|
+
const firstPstnCorrelationId = meeting.pstnCorrelationId;
|
6596
|
+
|
6401
6597
|
meeting.meetingRequest.dialOut.resetHistory();
|
6402
6598
|
|
6403
6599
|
// try again. the dial out urls should match
|
6404
6600
|
await meeting.usePhoneAudio(phoneNumber);
|
6405
6601
|
|
6406
6602
|
assert.calledWith(meeting.meetingRequest.dialOut, {
|
6407
|
-
correlationId: meeting.
|
6603
|
+
correlationId: meeting.pstnCorrelationId,
|
6408
6604
|
dialOutUrl: DIAL_OUT_URL,
|
6409
6605
|
locusUrl: meeting.locusUrl,
|
6410
6606
|
clientUrl: meeting.deviceUrl,
|
6411
6607
|
phoneNumber,
|
6412
6608
|
});
|
6413
6609
|
assert.notCalled(meeting.meetingRequest.dialIn);
|
6610
|
+
// A new PSTN correlationId should be generated for the second attempt
|
6611
|
+
assert.notEqual(
|
6612
|
+
meeting.pstnCorrelationId,
|
6613
|
+
firstPstnCorrelationId,
|
6614
|
+
'pstnCorrelationId should be regenerated on each dial-out attempt'
|
6615
|
+
);
|
6414
6616
|
});
|
6415
6617
|
|
6416
|
-
it('rejects if the request failed (dial in)', () => {
|
6417
|
-
const error = '
|
6618
|
+
it('rejects if the request failed (dial in)', async () => {
|
6619
|
+
const error = {error: {message: 'dial in failed'}, stack: 'error stack'};
|
6418
6620
|
|
6419
6621
|
meeting.meetingRequest.dialIn = sinon.stub().returns(Promise.reject(error));
|
6420
6622
|
|
6421
|
-
|
6422
|
-
.usePhoneAudio()
|
6423
|
-
|
6424
|
-
|
6425
|
-
|
6426
|
-
|
6427
|
-
|
6623
|
+
try {
|
6624
|
+
await meeting.usePhoneAudio();
|
6625
|
+
throw new Error('Promise resolved when it should have rejected');
|
6626
|
+
} catch (e) {
|
6627
|
+
assert.equal(e, error);
|
6628
|
+
|
6629
|
+
// Verify behavioral metric was sent with dial_in_correlation_id
|
6630
|
+
assert.calledWith(Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.ADD_DIAL_IN_FAILURE, {
|
6631
|
+
correlation_id: meeting.correlationId,
|
6632
|
+
dial_in_url: meeting.dialInUrl,
|
6633
|
+
dial_in_correlation_id: sinon.match.string,
|
6634
|
+
locus_id: meeting.locusUrl.split('/').pop(),
|
6635
|
+
client_url: meeting.deviceUrl,
|
6636
|
+
reason: error.error.message,
|
6637
|
+
stack: error.stack,
|
6428
6638
|
});
|
6639
|
+
|
6640
|
+
// Verify pstnCorrelationId was cleared after error
|
6641
|
+
assert.equal(meeting.pstnCorrelationId, undefined);
|
6642
|
+
}
|
6429
6643
|
});
|
6430
6644
|
|
6431
6645
|
it('rejects if the request failed (dial out)', async () => {
|
6432
|
-
const error = '
|
6646
|
+
const error = {error: {message: 'dial out failed'}, stack: 'error stack'};
|
6433
6647
|
|
6434
6648
|
meeting.meetingRequest.dialOut = sinon.stub().returns(Promise.reject(error));
|
6435
6649
|
|
6436
|
-
|
6437
|
-
.usePhoneAudio('+441234567890')
|
6438
|
-
|
6439
|
-
|
6440
|
-
|
6441
|
-
|
6442
|
-
|
6650
|
+
try {
|
6651
|
+
await meeting.usePhoneAudio('+441234567890');
|
6652
|
+
throw new Error('Promise resolved when it should have rejected');
|
6653
|
+
} catch (e) {
|
6654
|
+
assert.equal(e, error);
|
6655
|
+
|
6656
|
+
// Verify behavioral metric was sent with dial_out_correlation_id
|
6657
|
+
assert.calledWith(Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.ADD_DIAL_OUT_FAILURE, {
|
6658
|
+
correlation_id: meeting.correlationId,
|
6659
|
+
dial_out_url: meeting.dialOutUrl,
|
6660
|
+
dial_out_correlation_id: sinon.match.string,
|
6661
|
+
locus_id: meeting.locusUrl.split('/').pop(),
|
6662
|
+
client_url: meeting.deviceUrl,
|
6663
|
+
reason: error.error.message,
|
6664
|
+
stack: error.stack,
|
6443
6665
|
});
|
6666
|
+
|
6667
|
+
// Verify pstnCorrelationId was cleared after error
|
6668
|
+
assert.equal(meeting.pstnCorrelationId, undefined);
|
6669
|
+
}
|
6670
|
+
});
|
6671
|
+
});
|
6672
|
+
|
6673
|
+
describe('#disconnectPhoneAudio', () => {
|
6674
|
+
beforeEach(() => {
|
6675
|
+
// Mock the MeetingUtil.disconnectPhoneAudio method
|
6676
|
+
sinon.stub(MeetingUtil, 'disconnectPhoneAudio').resolves();
|
6677
|
+
meeting.dialInUrl = 'dialin:///test-dial-in-url';
|
6678
|
+
meeting.dialOutUrl = 'dialout:///test-dial-out-url';
|
6679
|
+
meeting.dialInDeviceStatus = 'JOINED';
|
6680
|
+
meeting.dialOutDeviceStatus = 'JOINED';
|
6681
|
+
});
|
6682
|
+
|
6683
|
+
afterEach(() => {
|
6684
|
+
MeetingUtil.disconnectPhoneAudio.restore();
|
6685
|
+
});
|
6686
|
+
|
6687
|
+
it('should disconnect phone audio and clear pstnCorrelationId', async () => {
|
6688
|
+
meeting.pstnCorrelationId = 'test-pstn-correlation-id';
|
6689
|
+
|
6690
|
+
await meeting.disconnectPhoneAudio();
|
6691
|
+
|
6692
|
+
// Verify that pstnCorrelationId is cleared
|
6693
|
+
assert.equal(meeting.pstnCorrelationId, undefined);
|
6694
|
+
|
6695
|
+
// Verify that MeetingUtil.disconnectPhoneAudio was called for both dial-in and dial-out
|
6696
|
+
assert.calledTwice(MeetingUtil.disconnectPhoneAudio);
|
6697
|
+
assert.calledWith(MeetingUtil.disconnectPhoneAudio, meeting, meeting.dialInUrl);
|
6698
|
+
assert.calledWith(MeetingUtil.disconnectPhoneAudio, meeting, meeting.dialOutUrl);
|
6699
|
+
});
|
6700
|
+
|
6701
|
+
it('should handle case when no PSTN connection is active', async () => {
|
6702
|
+
meeting.dialInDeviceStatus = 'IDLE';
|
6703
|
+
meeting.dialOutDeviceStatus = 'IDLE';
|
6704
|
+
meeting.pstnCorrelationId = 'test-pstn-correlation-id';
|
6705
|
+
|
6706
|
+
await meeting.disconnectPhoneAudio();
|
6707
|
+
|
6708
|
+
// Verify that pstnCorrelationId is still cleared even when no phone connection is active
|
6709
|
+
assert.equal(meeting.pstnCorrelationId, undefined);
|
6710
|
+
// And verify no disconnect was attempted
|
6711
|
+
assert.notCalled(MeetingUtil.disconnectPhoneAudio);
|
6444
6712
|
});
|
6445
6713
|
});
|
6446
6714
|
|
@@ -7957,6 +8225,7 @@ describe('plugin-meetings', () => {
|
|
7957
8225
|
|
7958
8226
|
meeting.requestScreenShareFloor = sinon.stub().resolves({});
|
7959
8227
|
meeting.releaseScreenShareFloor = sinon.stub().resolves({});
|
8228
|
+
webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp = sinon.stub();
|
7960
8229
|
meeting.mediaProperties.mediaDirection = {
|
7961
8230
|
sendAudio: 'fake value', // using non-boolean here so that we can check that these values are untouched in tests
|
7962
8231
|
sendVideo: 'fake value',
|
@@ -8038,6 +8307,12 @@ describe('plugin-meetings', () => {
|
|
8038
8307
|
payload: {mediaType: 'share', shareInstanceId: meeting.localShareInstanceId},
|
8039
8308
|
options: {meetingId: meeting.id},
|
8040
8309
|
});
|
8310
|
+
|
8311
|
+
// ensure the share start timestamp is saved
|
8312
|
+
assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, {
|
8313
|
+
key: 'internal.client.share.initiated',
|
8314
|
+
});
|
8315
|
+
|
8041
8316
|
assert.equal(meeting.mediaProperties.mediaDirection.sendShare, true);
|
8042
8317
|
|
8043
8318
|
assert.equal(meeting.shareCAEventSentStatus.transmitStart, false);
|
@@ -8056,6 +8331,11 @@ describe('plugin-meetings', () => {
|
|
8056
8331
|
options: {meetingId: meeting.id},
|
8057
8332
|
});
|
8058
8333
|
|
8334
|
+
// ensure the share start timestamp is saved
|
8335
|
+
assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, {
|
8336
|
+
key: 'internal.client.share.initiated',
|
8337
|
+
});
|
8338
|
+
|
8059
8339
|
assert.calledWith(
|
8060
8340
|
meeting.sendSlotManager.getSlot(MediaType.AudioSlides).publishStream,
|
8061
8341
|
stream
|
@@ -10011,6 +10291,24 @@ describe('plugin-meetings', () => {
|
|
10011
10291
|
);
|
10012
10292
|
});
|
10013
10293
|
|
10294
|
+
it('listens to CONTROLS_POLLING_QA_CHANGED', async () => {
|
10295
|
+
const state = {example: 'value'};
|
10296
|
+
|
10297
|
+
await meeting.locusInfo.emitScoped(
|
10298
|
+
{function: 'test', file: 'test'},
|
10299
|
+
LOCUSINFO.EVENTS.CONTROLS_POLLING_QA_CHANGED,
|
10300
|
+
{state}
|
10301
|
+
);
|
10302
|
+
|
10303
|
+
assert.calledWith(
|
10304
|
+
TriggerProxy.trigger,
|
10305
|
+
meeting,
|
10306
|
+
{file: 'meeting/index', function: 'setupLocusControlsListener'},
|
10307
|
+
EVENT_TRIGGERS.MEETING_CONTROLS_POLLING_QA_UPDATED,
|
10308
|
+
{state}
|
10309
|
+
);
|
10310
|
+
});
|
10311
|
+
|
10014
10312
|
it('listens to the locus interpretation update event', () => {
|
10015
10313
|
const interpretation = {
|
10016
10314
|
siLanguages: [{languageCode: 20, languageName: 'en'}],
|
@@ -10311,6 +10609,8 @@ describe('plugin-meetings', () => {
|
|
10311
10609
|
meeting.mediaProperties = {mediaDirection: {sendShare: true}};
|
10312
10610
|
meeting.meetingRequest.changeMeetingFloor = sinon.stub().returns(Promise.resolve());
|
10313
10611
|
(meeting.deviceUrl = 'deviceUrl.com'), (meeting.localShareInstanceId = '1234-5678');
|
10612
|
+
webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp = sinon.stub();
|
10613
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getShareDuration = sinon.stub().returns(1000);
|
10314
10614
|
});
|
10315
10615
|
it('should call changeMeetingFloor()', async () => {
|
10316
10616
|
meeting.screenShareFloorState = 'GRANTED';
|
@@ -10328,6 +10628,22 @@ describe('plugin-meetings', () => {
|
|
10328
10628
|
assert.exists(share.then);
|
10329
10629
|
await share;
|
10330
10630
|
assert.calledOnce(meeting.meetingRequest.changeMeetingFloor);
|
10631
|
+
|
10632
|
+
// ensure the share stop timestamp is saved
|
10633
|
+
assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, {
|
10634
|
+
key: 'internal.client.share.stopped',
|
10635
|
+
});
|
10636
|
+
|
10637
|
+
// ensure the CA share stopped metric is submitted with duration
|
10638
|
+
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
10639
|
+
name: 'client.share.stopped',
|
10640
|
+
payload: {
|
10641
|
+
mediaType: 'share',
|
10642
|
+
shareInstanceId: meeting.localShareInstanceId,
|
10643
|
+
shareDuration: 1000,
|
10644
|
+
},
|
10645
|
+
options: {meetingId: meeting.id},
|
10646
|
+
});
|
10331
10647
|
});
|
10332
10648
|
it('should not call changeMeetingFloor() if someone else already has the floor', async () => {
|
10333
10649
|
// change selfId so that it doesn't match the beneficiary id from meeting.locusInfo.mediaShares
|
@@ -11603,6 +11919,14 @@ describe('plugin-meetings', () => {
|
|
11603
11919
|
requiredHints: [DISPLAY_HINTS.DISABLE_RDC_MEETING_OPTION],
|
11604
11920
|
displayHints: userDisplayHints,
|
11605
11921
|
});
|
11922
|
+
assert.calledWith(ControlsOptionsUtil.hasHints, {
|
11923
|
+
requiredHints: [DISPLAY_HINTS.ENABLE_ATTENDEE_START_POLLING_QA],
|
11924
|
+
displayHints: userDisplayHints,
|
11925
|
+
});
|
11926
|
+
assert.calledWith(ControlsOptionsUtil.hasHints, {
|
11927
|
+
requiredHints: [DISPLAY_HINTS.DISABLE_ATTENDEE_START_POLLING_QA],
|
11928
|
+
displayHints: userDisplayHints,
|
11929
|
+
});
|
11606
11930
|
|
11607
11931
|
assert.calledWith(
|
11608
11932
|
TriggerProxy.trigger,
|
@@ -11892,6 +12216,7 @@ describe('plugin-meetings', () => {
|
|
11892
12216
|
meeting.locusInfo.self = {url: url1};
|
11893
12217
|
meeting.meetingRequest.changeMeetingFloor = sinon.stub().returns(Promise.resolve());
|
11894
12218
|
meeting.deviceUrl = 'deviceUrl.com';
|
12219
|
+
webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp = sinon.stub();
|
11895
12220
|
});
|
11896
12221
|
it('should have #startWhiteboardShare', () => {
|
11897
12222
|
assert.exists(meeting.startWhiteboardShare);
|
@@ -11919,6 +12244,11 @@ describe('plugin-meetings', () => {
|
|
11919
12244
|
payload: {mediaType: 'whiteboard'},
|
11920
12245
|
options: {meetingId: meeting.id},
|
11921
12246
|
});
|
12247
|
+
|
12248
|
+
// ensure the share start timestamp is saved
|
12249
|
+
assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, {
|
12250
|
+
key: 'internal.client.share.initiated',
|
12251
|
+
});
|
11922
12252
|
});
|
11923
12253
|
});
|
11924
12254
|
describe('#stopWhiteboardShare', () => {
|
@@ -11930,6 +12260,8 @@ describe('plugin-meetings', () => {
|
|
11930
12260
|
meeting.locusInfo.self = {url: url1};
|
11931
12261
|
meeting.meetingRequest.changeMeetingFloor = sinon.stub().returns(Promise.resolve());
|
11932
12262
|
meeting.deviceUrl = 'deviceUrl.com';
|
12263
|
+
webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp = sinon.stub();
|
12264
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getShareDuration = sinon.stub().returns(1000);
|
11933
12265
|
});
|
11934
12266
|
it('should stop the whiteboard share', async () => {
|
11935
12267
|
const whiteboardShare = meeting.stopWhiteboardShare();
|
@@ -11944,6 +12276,21 @@ describe('plugin-meetings', () => {
|
|
11944
12276
|
uri: url1,
|
11945
12277
|
});
|
11946
12278
|
assert.calledOnce(meeting.meetingRequest.changeMeetingFloor);
|
12279
|
+
|
12280
|
+
// ensure the share stop timestamp is saved
|
12281
|
+
assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, {
|
12282
|
+
key: 'internal.client.share.stopped',
|
12283
|
+
});
|
12284
|
+
|
12285
|
+
// ensure the CA share stopped metric is submitted with duration
|
12286
|
+
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
12287
|
+
name: 'client.share.stopped',
|
12288
|
+
payload: {
|
12289
|
+
mediaType: 'whiteboard',
|
12290
|
+
shareDuration: 1000,
|
12291
|
+
},
|
12292
|
+
options: {meetingId: meeting.id},
|
12293
|
+
});
|
11947
12294
|
});
|
11948
12295
|
});
|
11949
12296
|
});
|
@@ -12242,7 +12589,7 @@ describe('plugin-meetings', () => {
|
|
12242
12589
|
activeSharingId.whiteboard = beneficiaryId;
|
12243
12590
|
|
12244
12591
|
eventTrigger.share.push(
|
12245
|
-
meeting.webinar.selfIsAttendee
|
12592
|
+
meeting.webinar.selfIsAttendee || meeting.guest
|
12246
12593
|
? {
|
12247
12594
|
eventName: EVENT_TRIGGERS.MEETING_STARTED_SHARING_REMOTE,
|
12248
12595
|
functionName: 'remoteShare',
|
@@ -12261,7 +12608,8 @@ describe('plugin-meetings', () => {
|
|
12261
12608
|
}
|
12262
12609
|
);
|
12263
12610
|
|
12264
|
-
shareStatus =
|
12611
|
+
shareStatus =
|
12612
|
+
meeting.webinar.selfIsAttendee || meeting.guest
|
12265
12613
|
? SHARE_STATUS.REMOTE_SHARE_ACTIVE
|
12266
12614
|
: SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE;
|
12267
12615
|
}
|
@@ -12479,6 +12827,36 @@ describe('plugin-meetings', () => {
|
|
12479
12827
|
});
|
12480
12828
|
});
|
12481
12829
|
|
12830
|
+
describe('Whiteboard Share - User is guest', () => {
|
12831
|
+
it('User receives a remote share instead of whiteboard share', () => {
|
12832
|
+
// Set the guest flag
|
12833
|
+
meeting.guest = true;
|
12834
|
+
|
12835
|
+
// Step 1: Start sharing whiteboard A
|
12836
|
+
const data1 = generateData(
|
12837
|
+
blankPayload, // Initial payload
|
12838
|
+
true, // isGranting: Granting share
|
12839
|
+
false, // isContent: Whiteboard (not content)
|
12840
|
+
USER_IDS.REMOTE_A, // Beneficiary ID: Remote user A
|
12841
|
+
RESOURCE_URLS.WHITEBOARD_A // Resource URL: Whiteboard A
|
12842
|
+
);
|
12843
|
+
|
12844
|
+
// Step 2: Stop sharing whiteboard A
|
12845
|
+
const data2 = generateData(
|
12846
|
+
data1.payload, // Updated payload from Step 1
|
12847
|
+
false, // isGranting: Stopping share
|
12848
|
+
false, // isContent: Whiteboard
|
12849
|
+
USER_IDS.REMOTE_A // Beneficiary ID: Remote user A
|
12850
|
+
);
|
12851
|
+
|
12852
|
+
// Validate the payload changes and status updates
|
12853
|
+
payloadTestHelper([data1]);
|
12854
|
+
|
12855
|
+
// Specific assertions for guest
|
12856
|
+
assert.equal(meeting.shareStatus, SHARE_STATUS.REMOTE_SHARE_ACTIVE);
|
12857
|
+
});
|
12858
|
+
});
|
12859
|
+
|
12482
12860
|
describe('Whiteboard A --> Whiteboard B', () => {
|
12483
12861
|
it('Scenario #1: you share both whiteboards', () => {
|
12484
12862
|
const data1 = generateData(
|
@@ -13923,4 +14301,443 @@ describe('plugin-meetings', () => {
|
|
13923
14301
|
assert.equal(result.failureReason, MEETING_INFO_FAILURE_REASON.WRONG_CAPTCHA);
|
13924
14302
|
});
|
13925
14303
|
});
|
14304
|
+
|
14305
|
+
describe('#setStage', () => {
|
14306
|
+
const check = async (options, expectedVideoLayout) => {
|
14307
|
+
const locusUrl = `https://locus-test.wbx2.com/locus/api/v1/loci/${uuidv4()}`;
|
14308
|
+
meeting.locusUrl = locusUrl;
|
14309
|
+
|
14310
|
+
const setStagePromise = meeting.setStage(options);
|
14311
|
+
|
14312
|
+
assert.exists(setStagePromise.then);
|
14313
|
+
await setStagePromise;
|
14314
|
+
|
14315
|
+
assert.calledOnceWithExactly(
|
14316
|
+
meeting.meetingRequest.synchronizeStage,
|
14317
|
+
locusUrl,
|
14318
|
+
expectedVideoLayout
|
14319
|
+
);
|
14320
|
+
};
|
14321
|
+
|
14322
|
+
beforeEach(() => {
|
14323
|
+
meeting.meetingRequest.synchronizeStage = sinon.stub().returns(Promise.resolve());
|
14324
|
+
});
|
14325
|
+
|
14326
|
+
it('sends the expected request when no options are provided', async () => {
|
14327
|
+
await check(undefined, {
|
14328
|
+
overrideDefault: true,
|
14329
|
+
lockAttendeeViewOnStageOnly: false,
|
14330
|
+
stageParameters: {
|
14331
|
+
activeSpeakerProportion: 0.5,
|
14332
|
+
showActiveSpeaker: {show: false, order: 0},
|
14333
|
+
stageManagerType: 0,
|
14334
|
+
},
|
14335
|
+
});
|
14336
|
+
});
|
14337
|
+
|
14338
|
+
it('sends the expected request when empty options are provided', async () => {
|
14339
|
+
await check(
|
14340
|
+
{},
|
14341
|
+
{
|
14342
|
+
overrideDefault: true,
|
14343
|
+
lockAttendeeViewOnStageOnly: false,
|
14344
|
+
stageParameters: {
|
14345
|
+
activeSpeakerProportion: 0.5,
|
14346
|
+
showActiveSpeaker: {show: false, order: 0},
|
14347
|
+
stageManagerType: 0,
|
14348
|
+
},
|
14349
|
+
}
|
14350
|
+
);
|
14351
|
+
});
|
14352
|
+
|
14353
|
+
[0.25, 0.5, 0.75].forEach((activeSpeakerProportion) => {
|
14354
|
+
it(`sends the expected request when only the active speaker proportion option is provided as ${activeSpeakerProportion}`, async () => {
|
14355
|
+
await check(
|
14356
|
+
{activeSpeakerProportion},
|
14357
|
+
{
|
14358
|
+
overrideDefault: true,
|
14359
|
+
lockAttendeeViewOnStageOnly: false,
|
14360
|
+
stageParameters: {
|
14361
|
+
activeSpeakerProportion,
|
14362
|
+
showActiveSpeaker: {show: false, order: 0},
|
14363
|
+
stageManagerType: 0,
|
14364
|
+
},
|
14365
|
+
}
|
14366
|
+
);
|
14367
|
+
});
|
14368
|
+
});
|
14369
|
+
|
14370
|
+
it('sends the expected request when only the custom background option is provided', async () => {
|
14371
|
+
const customBackground = {
|
14372
|
+
url: `https://test.wbx2.com/background/${uuidv4()}.jpg`,
|
14373
|
+
};
|
14374
|
+
|
14375
|
+
await check(
|
14376
|
+
{customBackground},
|
14377
|
+
{
|
14378
|
+
overrideDefault: true,
|
14379
|
+
lockAttendeeViewOnStageOnly: false,
|
14380
|
+
stageParameters: {
|
14381
|
+
activeSpeakerProportion: 0.5,
|
14382
|
+
showActiveSpeaker: {show: false, order: 0},
|
14383
|
+
stageManagerType: 2,
|
14384
|
+
},
|
14385
|
+
customLayouts: {background: customBackground},
|
14386
|
+
}
|
14387
|
+
);
|
14388
|
+
});
|
14389
|
+
|
14390
|
+
it('sends the expected request when only the custom logo option is provided', async () => {
|
14391
|
+
const customLogo = {
|
14392
|
+
url: `https://test.wbx2.com/logo/${uuidv4()}.png`,
|
14393
|
+
position: 'LowerRight',
|
14394
|
+
};
|
14395
|
+
|
14396
|
+
await check(
|
14397
|
+
{customLogo},
|
14398
|
+
{
|
14399
|
+
overrideDefault: true,
|
14400
|
+
lockAttendeeViewOnStageOnly: false,
|
14401
|
+
stageParameters: {
|
14402
|
+
activeSpeakerProportion: 0.5,
|
14403
|
+
showActiveSpeaker: {show: false, order: 0},
|
14404
|
+
stageManagerType: 1,
|
14405
|
+
},
|
14406
|
+
customLayouts: {logo: customLogo},
|
14407
|
+
}
|
14408
|
+
);
|
14409
|
+
});
|
14410
|
+
|
14411
|
+
it('sends the expected request when only the custom name label option is provided', async () => {
|
14412
|
+
const customNameLabel = {
|
14413
|
+
accentColor: '#0A7806',
|
14414
|
+
background: {color: 'rgba(255, 255, 255, 1)'},
|
14415
|
+
border: {color: 'rgba(255, 255, 255, 1)'},
|
14416
|
+
content: {
|
14417
|
+
displayName: {color: 'rgba(0, 0, 0, 0.95)'},
|
14418
|
+
subtitle: {color: 'rgba(0, 0, 0, 0.6)'},
|
14419
|
+
},
|
14420
|
+
decoration: {color: 'rgba(10, 120, 6, 1)'},
|
14421
|
+
fadeOut: {delay: 15},
|
14422
|
+
type: 'Primary',
|
14423
|
+
};
|
14424
|
+
|
14425
|
+
await check(
|
14426
|
+
{customNameLabel},
|
14427
|
+
{
|
14428
|
+
overrideDefault: true,
|
14429
|
+
lockAttendeeViewOnStageOnly: false,
|
14430
|
+
stageParameters: {
|
14431
|
+
activeSpeakerProportion: 0.5,
|
14432
|
+
showActiveSpeaker: {show: false, order: 0},
|
14433
|
+
stageManagerType: 4,
|
14434
|
+
},
|
14435
|
+
nameLabelStyle: customNameLabel,
|
14436
|
+
}
|
14437
|
+
);
|
14438
|
+
});
|
14439
|
+
|
14440
|
+
it('sends the expected request when only the custom background and logo options are provided', async () => {
|
14441
|
+
const customBackground = {
|
14442
|
+
url: `https://test.wbx2.com/background/${uuidv4()}.jpg`,
|
14443
|
+
};
|
14444
|
+
const customLogo = {
|
14445
|
+
url: `https://test.wbx2.com/logo/${uuidv4()}.png`,
|
14446
|
+
position: 'UpperRight',
|
14447
|
+
};
|
14448
|
+
|
14449
|
+
await check(
|
14450
|
+
{customBackground, customLogo},
|
14451
|
+
{
|
14452
|
+
overrideDefault: true,
|
14453
|
+
lockAttendeeViewOnStageOnly: false,
|
14454
|
+
stageParameters: {
|
14455
|
+
activeSpeakerProportion: 0.5,
|
14456
|
+
showActiveSpeaker: {show: false, order: 0},
|
14457
|
+
stageManagerType: 3,
|
14458
|
+
},
|
14459
|
+
customLayouts: {background: customBackground, logo: customLogo},
|
14460
|
+
}
|
14461
|
+
);
|
14462
|
+
});
|
14463
|
+
|
14464
|
+
it('sends the expected request when only the custom background and name label options are provided', async () => {
|
14465
|
+
const customBackground = {
|
14466
|
+
url: `https://test.wbx2.com/background/${uuidv4()}.jpg`,
|
14467
|
+
};
|
14468
|
+
const customNameLabel = {
|
14469
|
+
accentColor: '#00A3FF',
|
14470
|
+
background: {color: 'rgba(0, 163, 255, 1)'},
|
14471
|
+
border: {color: 'rgba(0, 163, 255, 1)'},
|
14472
|
+
content: {
|
14473
|
+
displayName: {color: 'rgba(255, 255, 255, 0.95)'},
|
14474
|
+
subtitle: {color: 'rgba(255, 255, 255, 0.7)'},
|
14475
|
+
},
|
14476
|
+
decoration: {color: 'rgba(255, 255, 255, 0.95)'},
|
14477
|
+
fadeOut: {delay: 15},
|
14478
|
+
type: 'PrimaryInverted',
|
14479
|
+
};
|
14480
|
+
|
14481
|
+
await check(
|
14482
|
+
{customBackground, customNameLabel},
|
14483
|
+
{
|
14484
|
+
overrideDefault: true,
|
14485
|
+
lockAttendeeViewOnStageOnly: false,
|
14486
|
+
stageParameters: {
|
14487
|
+
activeSpeakerProportion: 0.5,
|
14488
|
+
showActiveSpeaker: {show: false, order: 0},
|
14489
|
+
stageManagerType: 6,
|
14490
|
+
},
|
14491
|
+
customLayouts: {background: customBackground},
|
14492
|
+
nameLabelStyle: customNameLabel,
|
14493
|
+
}
|
14494
|
+
);
|
14495
|
+
});
|
14496
|
+
|
14497
|
+
it('sends the expected request when only the custom logo and name label options are provided', async () => {
|
14498
|
+
const customLogo = {
|
14499
|
+
url: `https://test.wbx2.com/logo/${uuidv4()}.png`,
|
14500
|
+
position: 'UpperLeft',
|
14501
|
+
};
|
14502
|
+
const customNameLabel = {
|
14503
|
+
accentColor: '#942B2B',
|
14504
|
+
background: {color: 'rgba(255, 255, 255, 1)'},
|
14505
|
+
border: {color: 'rgba(148, 43, 43, 1)'},
|
14506
|
+
content: {
|
14507
|
+
displayName: {color: 'rgba(0, 0, 0, 0.95)'},
|
14508
|
+
subtitle: {color: 'rgba(0, 0, 0, 0.6)'},
|
14509
|
+
},
|
14510
|
+
decoration: {color: 'rgba(0, 0, 0, 0)'},
|
14511
|
+
fadeOut: {delay: 15},
|
14512
|
+
type: 'Secondary',
|
14513
|
+
};
|
14514
|
+
|
14515
|
+
await check(
|
14516
|
+
{customLogo, customNameLabel},
|
14517
|
+
{
|
14518
|
+
overrideDefault: true,
|
14519
|
+
lockAttendeeViewOnStageOnly: false,
|
14520
|
+
stageParameters: {
|
14521
|
+
activeSpeakerProportion: 0.5,
|
14522
|
+
showActiveSpeaker: {show: false, order: 0},
|
14523
|
+
stageManagerType: 5,
|
14524
|
+
},
|
14525
|
+
customLayouts: {logo: customLogo},
|
14526
|
+
nameLabelStyle: customNameLabel,
|
14527
|
+
}
|
14528
|
+
);
|
14529
|
+
});
|
14530
|
+
|
14531
|
+
it('sends the expected request when only the custom background, logo, name label options are provided', async () => {
|
14532
|
+
const customBackground = {
|
14533
|
+
url: `https://test.wbx2.com/background/${uuidv4()}.jpg`,
|
14534
|
+
};
|
14535
|
+
const customLogo = {
|
14536
|
+
url: `https://test.wbx2.com/logo/${uuidv4()}.png`,
|
14537
|
+
position: 'LowerLeft',
|
14538
|
+
};
|
14539
|
+
const customNameLabel = {
|
14540
|
+
accentColor: '#EBD960',
|
14541
|
+
background: {color: 'rgba(235, 217, 96, 0.55)'},
|
14542
|
+
border: {color: 'rgba(235, 217, 96, 0.55)'},
|
14543
|
+
content: {
|
14544
|
+
displayName: {color: 'rgba(255, 255, 255, 0.95)'},
|
14545
|
+
subtitle: {color: 'rgba(255, 255, 255, 0.7)'},
|
14546
|
+
},
|
14547
|
+
decoration: {color: 'rgba(0, 0, 0, 0)'},
|
14548
|
+
fadeOut: {delay: 15},
|
14549
|
+
type: 'SecondaryInverted',
|
14550
|
+
};
|
14551
|
+
|
14552
|
+
await check(
|
14553
|
+
{customBackground, customLogo, customNameLabel},
|
14554
|
+
{
|
14555
|
+
overrideDefault: true,
|
14556
|
+
lockAttendeeViewOnStageOnly: false,
|
14557
|
+
stageParameters: {
|
14558
|
+
activeSpeakerProportion: 0.5,
|
14559
|
+
showActiveSpeaker: {show: false, order: 0},
|
14560
|
+
stageManagerType: 7,
|
14561
|
+
},
|
14562
|
+
customLayouts: {background: customBackground, logo: customLogo},
|
14563
|
+
nameLabelStyle: customNameLabel,
|
14564
|
+
}
|
14565
|
+
);
|
14566
|
+
});
|
14567
|
+
|
14568
|
+
it('sends the expected request when only the important participants option is provided as empty', async () => {
|
14569
|
+
await check(
|
14570
|
+
{importantParticipants: []},
|
14571
|
+
{
|
14572
|
+
overrideDefault: true,
|
14573
|
+
lockAttendeeViewOnStageOnly: false,
|
14574
|
+
stageParameters: {
|
14575
|
+
activeSpeakerProportion: 0.5,
|
14576
|
+
showActiveSpeaker: {show: false, order: 0},
|
14577
|
+
stageManagerType: 0,
|
14578
|
+
},
|
14579
|
+
}
|
14580
|
+
);
|
14581
|
+
});
|
14582
|
+
|
14583
|
+
it('sends the expected request when only the important participants option is provided as populated', async () => {
|
14584
|
+
const importantParticipants = [
|
14585
|
+
{mainCsi: 11111111, participantId: uuidv4()},
|
14586
|
+
{mainCsi: 22222222, participantId: uuidv4()},
|
14587
|
+
{mainCsi: 33333333, participantId: uuidv4()},
|
14588
|
+
{mainCsi: 44444444, participantId: uuidv4()},
|
14589
|
+
{mainCsi: 55555555, participantId: uuidv4()},
|
14590
|
+
{mainCsi: 66666666, participantId: uuidv4()},
|
14591
|
+
{mainCsi: 77777777, participantId: uuidv4()},
|
14592
|
+
{mainCsi: 88888888, participantId: uuidv4()},
|
14593
|
+
];
|
14594
|
+
|
14595
|
+
await check(
|
14596
|
+
{importantParticipants},
|
14597
|
+
{
|
14598
|
+
overrideDefault: true,
|
14599
|
+
lockAttendeeViewOnStageOnly: false,
|
14600
|
+
stageParameters: {
|
14601
|
+
activeSpeakerProportion: 0.5,
|
14602
|
+
importantParticipants: [
|
14603
|
+
{...importantParticipants[0], order: 1},
|
14604
|
+
{...importantParticipants[1], order: 2},
|
14605
|
+
{...importantParticipants[2], order: 3},
|
14606
|
+
{...importantParticipants[3], order: 4},
|
14607
|
+
{...importantParticipants[4], order: 5},
|
14608
|
+
{...importantParticipants[5], order: 6},
|
14609
|
+
{...importantParticipants[6], order: 7},
|
14610
|
+
{...importantParticipants[7], order: 8},
|
14611
|
+
],
|
14612
|
+
showActiveSpeaker: {show: false, order: 0},
|
14613
|
+
stageManagerType: 0,
|
14614
|
+
},
|
14615
|
+
}
|
14616
|
+
);
|
14617
|
+
});
|
14618
|
+
|
14619
|
+
[false, true].forEach((lockAttendeeViewOnStage) => {
|
14620
|
+
it(`sends the expected request when only the lock attendee view on stage option is provided as ${lockAttendeeViewOnStage}`, async () => {
|
14621
|
+
await check(
|
14622
|
+
{lockAttendeeViewOnStage},
|
14623
|
+
{
|
14624
|
+
overrideDefault: true,
|
14625
|
+
lockAttendeeViewOnStageOnly: lockAttendeeViewOnStage,
|
14626
|
+
stageParameters: {
|
14627
|
+
activeSpeakerProportion: 0.5,
|
14628
|
+
showActiveSpeaker: {show: false, order: 0},
|
14629
|
+
stageManagerType: 0,
|
14630
|
+
},
|
14631
|
+
}
|
14632
|
+
);
|
14633
|
+
});
|
14634
|
+
});
|
14635
|
+
|
14636
|
+
[false, true].forEach((showActiveSpeaker) => {
|
14637
|
+
it(`sends the expected request when only the show active speaker option is provided as ${showActiveSpeaker}`, async () => {
|
14638
|
+
await check(
|
14639
|
+
{showActiveSpeaker},
|
14640
|
+
{
|
14641
|
+
overrideDefault: true,
|
14642
|
+
lockAttendeeViewOnStageOnly: false,
|
14643
|
+
stageParameters: {
|
14644
|
+
activeSpeakerProportion: 0.5,
|
14645
|
+
showActiveSpeaker: {show: showActiveSpeaker, order: 0},
|
14646
|
+
stageManagerType: 0,
|
14647
|
+
},
|
14648
|
+
}
|
14649
|
+
);
|
14650
|
+
});
|
14651
|
+
});
|
14652
|
+
|
14653
|
+
it('sends the expected request when all options are provided', async () => {
|
14654
|
+
const activeSpeakerProportion = 0.6;
|
14655
|
+
const customBackground = {
|
14656
|
+
url: `https://test.wbx2.com/background/${uuidv4()}.jpg`,
|
14657
|
+
};
|
14658
|
+
const customLogo = {
|
14659
|
+
url: `https://test.wbx2.com/logo/${uuidv4()}.png`,
|
14660
|
+
position: 'UpperMiddle',
|
14661
|
+
};
|
14662
|
+
const customNameLabel = {
|
14663
|
+
accentColor: '#0A7806',
|
14664
|
+
background: {color: 'rgba(255, 255, 255, 1)'},
|
14665
|
+
border: {color: 'rgba(255, 255, 255, 1)'},
|
14666
|
+
content: {
|
14667
|
+
displayName: {color: 'rgba(0, 0, 0, 0.95)'},
|
14668
|
+
subtitle: {color: 'rgba(0, 0, 0, 0.6)'},
|
14669
|
+
},
|
14670
|
+
decoration: {color: 'rgba(10, 120, 6, 1)'},
|
14671
|
+
fadeOut: {delay: 15},
|
14672
|
+
type: 'Primary',
|
14673
|
+
};
|
14674
|
+
const importantParticipants = [
|
14675
|
+
{mainCsi: 11111111, participantId: uuidv4()},
|
14676
|
+
{mainCsi: 22222222, participantId: uuidv4()},
|
14677
|
+
{mainCsi: 33333333, participantId: uuidv4()},
|
14678
|
+
{mainCsi: 44444444, participantId: uuidv4()},
|
14679
|
+
{mainCsi: 55555555, participantId: uuidv4()},
|
14680
|
+
{mainCsi: 66666666, participantId: uuidv4()},
|
14681
|
+
{mainCsi: 77777777, participantId: uuidv4()},
|
14682
|
+
{mainCsi: 88888888, participantId: uuidv4()},
|
14683
|
+
];
|
14684
|
+
const lockAttendeeViewOnStage = true;
|
14685
|
+
const showActiveSpeaker = true;
|
14686
|
+
|
14687
|
+
await check(
|
14688
|
+
{
|
14689
|
+
activeSpeakerProportion,
|
14690
|
+
customBackground,
|
14691
|
+
customLogo,
|
14692
|
+
customNameLabel,
|
14693
|
+
importantParticipants,
|
14694
|
+
lockAttendeeViewOnStage,
|
14695
|
+
showActiveSpeaker,
|
14696
|
+
},
|
14697
|
+
{
|
14698
|
+
overrideDefault: true,
|
14699
|
+
lockAttendeeViewOnStageOnly: lockAttendeeViewOnStage,
|
14700
|
+
stageParameters: {
|
14701
|
+
activeSpeakerProportion,
|
14702
|
+
importantParticipants: [
|
14703
|
+
{...importantParticipants[0], order: 1},
|
14704
|
+
{...importantParticipants[1], order: 2},
|
14705
|
+
{...importantParticipants[2], order: 3},
|
14706
|
+
{...importantParticipants[3], order: 4},
|
14707
|
+
{...importantParticipants[4], order: 5},
|
14708
|
+
{...importantParticipants[5], order: 6},
|
14709
|
+
{...importantParticipants[6], order: 7},
|
14710
|
+
{...importantParticipants[7], order: 8},
|
14711
|
+
],
|
14712
|
+
showActiveSpeaker: {show: showActiveSpeaker, order: 0},
|
14713
|
+
stageManagerType: 7,
|
14714
|
+
},
|
14715
|
+
customLayouts: {background: customBackground, logo: customLogo},
|
14716
|
+
nameLabelStyle: customNameLabel,
|
14717
|
+
}
|
14718
|
+
);
|
14719
|
+
});
|
14720
|
+
});
|
14721
|
+
|
14722
|
+
describe('#unsetStage', () => {
|
14723
|
+
beforeEach(() => {
|
14724
|
+
meeting.meetingRequest.synchronizeStage = sinon.stub().returns(Promise.resolve());
|
14725
|
+
});
|
14726
|
+
|
14727
|
+
it('sends the expected request', async () => {
|
14728
|
+
const locusUrl = `https://locus-test.wbx2.com/locus/api/v1/loci/${uuidv4()}`;
|
14729
|
+
meeting.locusUrl = locusUrl;
|
14730
|
+
|
14731
|
+
const unsetStagePromise = meeting.unsetStage();
|
14732
|
+
|
14733
|
+
assert.exists(unsetStagePromise.then);
|
14734
|
+
await unsetStagePromise;
|
14735
|
+
|
14736
|
+
assert.calledOnceWithExactly(
|
14737
|
+
meeting.meetingRequest.synchronizeStage,
|
14738
|
+
locusUrl,
|
14739
|
+
{overrideDefault: false}
|
14740
|
+
);
|
14741
|
+
});
|
14742
|
+
});
|
13926
14743
|
});
|