@webex/plugin-meetings 3.0.0 → 3.1.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/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +5 -4
- package/dist/constants.js +8 -4
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/interpretation/index.js +16 -2
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/mediaSharesUtils.js +15 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/selfUtils.js +5 -0
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.d.ts +61 -0
- package/dist/media/MediaConnectionAwaiter.js +163 -0
- package/dist/media/MediaConnectionAwaiter.js.map +1 -0
- package/dist/media/index.js +4 -1
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +4 -24
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/index.d.ts +26 -7
- package/dist/meeting/index.js +893 -677
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/muteState.d.ts +2 -8
- package/dist/meeting/muteState.js +37 -25
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.d.ts +3 -0
- package/dist/meeting/request.js +32 -23
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +1 -0
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +4 -1
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/index.d.ts +8 -0
- package/dist/meetings/index.js +20 -0
- package/dist/meetings/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.d.ts +2 -1
- package/dist/multistream/mediaRequestManager.js +1 -1
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.d.ts +2 -0
- package/dist/multistream/remoteMediaGroup.js +16 -2
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.d.ts +15 -0
- package/dist/multistream/remoteMediaManager.js +179 -65
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.d.ts +9 -1
- package/dist/multistream/sendSlotManager.js +22 -0
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/reachability/clusterReachability.d.ts +1 -0
- package/dist/reachability/clusterReachability.js +29 -15
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.d.ts +4 -0
- package/dist/reachability/index.js +18 -2
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +12 -10
- package/dist/reachability/request.js.map +1 -1
- package/dist/reachability/util.d.ts +7 -0
- package/dist/reachability/util.js +19 -0
- package/dist/reachability/util.js.map +1 -1
- package/dist/reconnection-manager/index.js +2 -1
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/index.d.ts +10 -2
- package/dist/roap/index.js +15 -0
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +3 -3
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.d.ts +64 -17
- package/dist/roap/turnDiscovery.js +307 -126
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/statsAnalyzer/index.js +53 -30
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/config.ts +1 -0
- package/src/constants.ts +7 -3
- package/src/index.ts +1 -0
- package/src/interpretation/index.ts +18 -1
- package/src/locus-info/mediaSharesUtils.ts +16 -0
- package/src/locus-info/selfUtils.ts +5 -0
- package/src/media/MediaConnectionAwaiter.ts +174 -0
- package/src/media/index.ts +3 -1
- package/src/media/properties.ts +6 -31
- package/src/meeting/index.ts +321 -106
- package/src/meeting/muteState.ts +34 -20
- package/src/meeting/request.ts +18 -2
- package/src/meeting/util.ts +1 -0
- package/src/meeting-info/utilv2.ts +2 -1
- package/src/meetings/index.ts +18 -0
- package/src/multistream/mediaRequestManager.ts +4 -1
- package/src/multistream/remoteMediaGroup.ts +19 -0
- package/src/multistream/remoteMediaManager.ts +101 -16
- package/src/multistream/sendSlotManager.ts +28 -0
- package/src/reachability/clusterReachability.ts +20 -5
- package/src/reachability/index.ts +24 -1
- package/src/reachability/request.ts +15 -11
- package/src/reachability/util.ts +21 -0
- package/src/reconnection-manager/index.ts +1 -1
- package/src/roap/index.ts +25 -3
- package/src/roap/request.ts +3 -3
- package/src/roap/turnDiscovery.ts +244 -78
- package/src/statsAnalyzer/index.ts +63 -27
- package/test/integration/spec/journey.js +14 -14
- package/test/integration/spec/space-meeting.js +1 -1
- package/test/unit/spec/interpretation/index.ts +39 -3
- package/test/unit/spec/locus-info/index.js +28 -19
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +9 -0
- package/test/unit/spec/locus-info/selfUtils.js +42 -12
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +344 -0
- package/test/unit/spec/media/index.ts +89 -78
- package/test/unit/spec/media/properties.ts +16 -70
- package/test/unit/spec/meeting/index.js +638 -139
- package/test/unit/spec/meeting/muteState.js +219 -67
- package/test/unit/spec/meeting/request.js +21 -0
- package/test/unit/spec/meeting/utils.js +6 -1
- package/test/unit/spec/meeting-info/utilv2.js +6 -0
- package/test/unit/spec/meetings/index.js +40 -20
- package/test/unit/spec/multistream/mediaRequestManager.ts +20 -2
- package/test/unit/spec/multistream/remoteMediaGroup.ts +79 -1
- package/test/unit/spec/multistream/remoteMediaManager.ts +199 -1
- package/test/unit/spec/multistream/sendSlotManager.ts +50 -18
- package/test/unit/spec/reachability/clusterReachability.ts +86 -22
- package/test/unit/spec/reachability/index.ts +197 -60
- package/test/unit/spec/reachability/request.js +15 -7
- package/test/unit/spec/reachability/util.ts +32 -2
- package/test/unit/spec/reconnection-manager/index.js +28 -0
- package/test/unit/spec/roap/index.ts +61 -6
- package/test/unit/spec/roap/turnDiscovery.ts +298 -16
- package/test/unit/spec/stats-analyzer/index.js +179 -0
- package/dist/member/member.types.d.ts +0 -11
- package/dist/member/member.types.js +0 -17
- package/dist/member/member.types.js.map +0 -1
- package/src/member/member.types.ts +0 -13
- /package/test/unit/spec/locus-info/{lib/selfConstant.js → selfConstant.js} +0 -0
|
@@ -7,7 +7,7 @@ import sinon from 'sinon';
|
|
|
7
7
|
import * as internalMediaModule from '@webex/internal-media-core';
|
|
8
8
|
import StateMachine from 'javascript-state-machine';
|
|
9
9
|
import uuid from 'uuid';
|
|
10
|
-
import {assert} from '@webex/test-helper-chai';
|
|
10
|
+
import {assert, expect} from '@webex/test-helper-chai';
|
|
11
11
|
import {Credentials, Token, WebexPlugin} from '@webex/webex-core';
|
|
12
12
|
import Support from '@webex/internal-plugin-support';
|
|
13
13
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
RemoteTrackType,
|
|
44
44
|
MediaType,
|
|
45
45
|
} from '@webex/internal-media-core';
|
|
46
|
-
import {
|
|
46
|
+
import {LocalStreamEventNames} from '@webex/media-helpers';
|
|
47
47
|
import * as StatsAnalyzerModule from '@webex/plugin-meetings/src/statsAnalyzer';
|
|
48
48
|
import EventsScope from '@webex/plugin-meetings/src/common/events/events-scope';
|
|
49
49
|
import Meetings, {CONSTANTS} from '@webex/plugin-meetings';
|
|
@@ -99,7 +99,6 @@ import {
|
|
|
99
99
|
MeetingInfoV2PolicyError,
|
|
100
100
|
} from '../../../../src/meeting-info/meeting-info-v2';
|
|
101
101
|
import {
|
|
102
|
-
CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD,
|
|
103
102
|
DTLS_HANDSHAKE_FAILED_CLIENT_CODE,
|
|
104
103
|
ICE_FAILED_WITHOUT_TURN_TLS_CLIENT_CODE,
|
|
105
104
|
ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE,
|
|
@@ -110,9 +109,7 @@ import CallDiagnosticMetrics from '@webex/internal-plugin-metrics/src/call-diagn
|
|
|
110
109
|
import {ERROR_DESCRIPTIONS} from '@webex/internal-plugin-metrics/src/call-diagnostic/config';
|
|
111
110
|
import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
|
|
112
111
|
|
|
113
|
-
import {
|
|
114
|
-
EVENT_TRIGGERS as VOICEAEVENTS,
|
|
115
|
-
} from '@webex/internal-plugin-voicea';
|
|
112
|
+
import {EVENT_TRIGGERS as VOICEAEVENTS} from '@webex/internal-plugin-voicea';
|
|
116
113
|
|
|
117
114
|
describe('plugin-meetings', () => {
|
|
118
115
|
const logger = {
|
|
@@ -613,36 +610,177 @@ describe('plugin-meetings', () => {
|
|
|
613
610
|
assert.exists(meeting.joinWithMedia);
|
|
614
611
|
});
|
|
615
612
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
613
|
+
const fakeRoapMessage = {id: 'fake TURN discovery message'};
|
|
614
|
+
const fakeReachabilityResults = {id: 'fake reachability'};
|
|
615
|
+
const fakeTurnServerInfo = {id: 'fake turn info'};
|
|
616
|
+
const fakeJoinResult = {id: 'join result'};
|
|
620
617
|
|
|
621
|
-
|
|
622
|
-
|
|
618
|
+
const joinOptions = {correlationId: '12345'};
|
|
619
|
+
const mediaOptions = {audioEnabled: true, allowMediaInLobby: true};
|
|
623
620
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
621
|
+
let generateTurnDiscoveryRequestMessageStub;
|
|
622
|
+
let handleTurnDiscoveryHttpResponseStub;
|
|
623
|
+
let abortTurnDiscoveryStub;
|
|
624
|
+
|
|
625
|
+
beforeEach(() => {
|
|
626
|
+
meeting.join = sinon.stub().returns(Promise.resolve(fakeJoinResult));
|
|
627
|
+
meeting.addMedia = sinon.stub().returns(Promise.resolve(test4));
|
|
628
|
+
|
|
629
|
+
webex.meetings.reachability.getReachabilityResults.resolves(fakeReachabilityResults);
|
|
630
|
+
|
|
631
|
+
generateTurnDiscoveryRequestMessageStub = sinon
|
|
632
|
+
.stub(meeting.roap, 'generateTurnDiscoveryRequestMessage')
|
|
633
|
+
.resolves({roapMessage: fakeRoapMessage});
|
|
634
|
+
handleTurnDiscoveryHttpResponseStub = sinon
|
|
635
|
+
.stub(meeting.roap, 'handleTurnDiscoveryHttpResponse')
|
|
636
|
+
.resolves({turnServerInfo: fakeTurnServerInfo, turnDiscoverySkippedReason: undefined});
|
|
637
|
+
abortTurnDiscoveryStub = sinon.stub(meeting.roap, 'abortTurnDiscovery');
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
it('should work as expected', async () => {
|
|
641
|
+
const result = await meeting.joinWithMedia({
|
|
642
|
+
joinOptions,
|
|
643
|
+
mediaOptions,
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
// check that TURN discovery is done with join and addMedia called
|
|
647
|
+
assert.calledOnceWithExactly(meeting.join, {
|
|
648
|
+
...joinOptions,
|
|
649
|
+
roapMessage: fakeRoapMessage,
|
|
650
|
+
reachability: fakeReachabilityResults,
|
|
651
|
+
});
|
|
652
|
+
assert.calledOnceWithExactly(generateTurnDiscoveryRequestMessageStub, meeting, true);
|
|
653
|
+
assert.calledOnceWithExactly(
|
|
654
|
+
handleTurnDiscoveryHttpResponseStub,
|
|
655
|
+
meeting,
|
|
656
|
+
fakeJoinResult
|
|
657
|
+
);
|
|
658
|
+
assert.calledOnceWithExactly(meeting.addMedia, mediaOptions, fakeTurnServerInfo);
|
|
659
|
+
|
|
660
|
+
assert.deepEqual(result, {join: fakeJoinResult, media: test4});
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
it("should not call handleTurnDiscoveryHttpResponse if we don't send a TURN discovery request with join", async () => {
|
|
664
|
+
generateTurnDiscoveryRequestMessageStub.resolves({roapMessage: undefined});
|
|
665
|
+
|
|
666
|
+
const result = await meeting.joinWithMedia({
|
|
667
|
+
joinOptions,
|
|
668
|
+
mediaOptions,
|
|
631
669
|
});
|
|
670
|
+
|
|
671
|
+
// check that TURN discovery is done with join and addMedia called
|
|
672
|
+
assert.calledOnceWithExactly(meeting.join, {
|
|
673
|
+
...joinOptions,
|
|
674
|
+
roapMessage: undefined,
|
|
675
|
+
reachability: fakeReachabilityResults,
|
|
676
|
+
});
|
|
677
|
+
assert.calledOnceWithExactly(generateTurnDiscoveryRequestMessageStub, meeting, true);
|
|
678
|
+
assert.notCalled(handleTurnDiscoveryHttpResponseStub);
|
|
679
|
+
assert.notCalled(abortTurnDiscoveryStub);
|
|
680
|
+
assert.calledOnceWithExactly(meeting.addMedia, mediaOptions, undefined);
|
|
681
|
+
|
|
682
|
+
assert.deepEqual(result, {join: fakeJoinResult, media: test4});
|
|
683
|
+
assert.equal(meeting.turnServerUsed, false);
|
|
632
684
|
});
|
|
633
685
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
686
|
+
it('should call abortTurnDiscovery() if we do not get a TURN server info', async () => {
|
|
687
|
+
handleTurnDiscoveryHttpResponseStub.resolves({
|
|
688
|
+
turnServerInfo: undefined,
|
|
689
|
+
turnDiscoverySkippedReason: 'missing http response',
|
|
638
690
|
});
|
|
639
691
|
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
692
|
+
const result = await meeting.joinWithMedia({
|
|
693
|
+
joinOptions,
|
|
694
|
+
mediaOptions,
|
|
695
|
+
});
|
|
643
696
|
|
|
644
|
-
|
|
697
|
+
// check that TURN discovery is done with join and addMedia called
|
|
698
|
+
assert.calledOnceWithExactly(meeting.join, {
|
|
699
|
+
...joinOptions,
|
|
700
|
+
roapMessage: fakeRoapMessage,
|
|
701
|
+
reachability: fakeReachabilityResults,
|
|
645
702
|
});
|
|
703
|
+
assert.calledOnceWithExactly(generateTurnDiscoveryRequestMessageStub, meeting, true);
|
|
704
|
+
assert.calledOnceWithExactly(
|
|
705
|
+
handleTurnDiscoveryHttpResponseStub,
|
|
706
|
+
meeting,
|
|
707
|
+
fakeJoinResult
|
|
708
|
+
);
|
|
709
|
+
assert.calledOnceWithExactly(abortTurnDiscoveryStub);
|
|
710
|
+
assert.calledOnceWithExactly(meeting.addMedia, mediaOptions, undefined);
|
|
711
|
+
|
|
712
|
+
assert.deepEqual(result, {join: fakeJoinResult, media: test4});
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
it('should reject if join() fails', async () => {
|
|
716
|
+
const error = new Error('fake');
|
|
717
|
+
meeting.join = sinon.stub().returns(Promise.reject(error));
|
|
718
|
+
meeting.locusUrl = null; // when join fails, we end up with null locusUrl
|
|
719
|
+
|
|
720
|
+
await assert.isRejected(meeting.joinWithMedia({mediaOptions: {allowMediaInLobby: true}}));
|
|
721
|
+
|
|
722
|
+
assert.calledOnceWithExactly(abortTurnDiscoveryStub);
|
|
723
|
+
|
|
724
|
+
assert.calledWith(
|
|
725
|
+
Metrics.sendBehavioralMetric,
|
|
726
|
+
BEHAVIORAL_METRICS.JOIN_WITH_MEDIA_FAILURE,
|
|
727
|
+
{
|
|
728
|
+
correlation_id: meeting.correlationId,
|
|
729
|
+
locus_id: undefined,
|
|
730
|
+
reason: error.message,
|
|
731
|
+
stack: error.stack,
|
|
732
|
+
leaveErrorReason: undefined,
|
|
733
|
+
},
|
|
734
|
+
{
|
|
735
|
+
type: error.name,
|
|
736
|
+
}
|
|
737
|
+
);
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
it('should fail if called with allowMediaInLobby:false', async () => {
|
|
741
|
+
meeting.join = sinon.stub().returns(Promise.resolve(test1));
|
|
742
|
+
meeting.addMedia = sinon.stub().returns(Promise.resolve(test4));
|
|
743
|
+
|
|
744
|
+
await assert.isRejected(
|
|
745
|
+
meeting.joinWithMedia({mediaOptions: {allowMediaInLobby: false}})
|
|
746
|
+
);
|
|
747
|
+
});
|
|
748
|
+
|
|
749
|
+
it('should call leave() if addMedia fails and ignore leave() failure', async () => {
|
|
750
|
+
const leaveError = new Error('leave error');
|
|
751
|
+
const addMediaError = new Error('fake addMedia error');
|
|
752
|
+
|
|
753
|
+
const leaveStub = sinon.stub(meeting, 'leave').rejects(leaveError);
|
|
754
|
+
meeting.addMedia = sinon.stub().rejects(addMediaError);
|
|
755
|
+
|
|
756
|
+
await assert.isRejected(
|
|
757
|
+
meeting.joinWithMedia({
|
|
758
|
+
joinOptions: {resourceId: 'some resource'},
|
|
759
|
+
mediaOptions: {allowMediaInLobby: true},
|
|
760
|
+
}),
|
|
761
|
+
addMediaError
|
|
762
|
+
);
|
|
763
|
+
|
|
764
|
+
assert.calledOnce(leaveStub);
|
|
765
|
+
assert.calledOnceWithExactly(leaveStub, {
|
|
766
|
+
resourceId: 'some resource',
|
|
767
|
+
reason: 'joinWithMedia failure',
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
assert.calledWith(
|
|
771
|
+
Metrics.sendBehavioralMetric,
|
|
772
|
+
BEHAVIORAL_METRICS.JOIN_WITH_MEDIA_FAILURE,
|
|
773
|
+
{
|
|
774
|
+
correlation_id: meeting.correlationId,
|
|
775
|
+
locus_id: meeting.locusUrl.split('/').pop(),
|
|
776
|
+
reason: addMediaError.message,
|
|
777
|
+
stack: addMediaError.stack,
|
|
778
|
+
leaveErrorReason: leaveError.message,
|
|
779
|
+
},
|
|
780
|
+
{
|
|
781
|
+
type: addMediaError.name,
|
|
782
|
+
}
|
|
783
|
+
);
|
|
646
784
|
});
|
|
647
785
|
});
|
|
648
786
|
|
|
@@ -669,7 +807,7 @@ describe('plugin-meetings', () => {
|
|
|
669
807
|
|
|
670
808
|
it('should subscribe to events for the first time and avoid subscribing for future transcription starts', async () => {
|
|
671
809
|
meeting.joinedWith = {
|
|
672
|
-
state: 'JOINED'
|
|
810
|
+
state: 'JOINED',
|
|
673
811
|
};
|
|
674
812
|
meeting.areVoiceaEventsSetup = false;
|
|
675
813
|
meeting.roles = ['MODERATOR'];
|
|
@@ -679,27 +817,19 @@ describe('plugin-meetings', () => {
|
|
|
679
817
|
assert.equal(webex.internal.voicea.on.callCount, 4);
|
|
680
818
|
assert.equal(meeting.areVoiceaEventsSetup, true);
|
|
681
819
|
assert.equal(webex.internal.voicea.listenToEvents.callCount, 1);
|
|
682
|
-
assert.calledWith(
|
|
683
|
-
webex.internal.voicea.toggleTranscribing,
|
|
684
|
-
true,
|
|
685
|
-
);
|
|
820
|
+
assert.calledWith(webex.internal.voicea.toggleTranscribing, true);
|
|
686
821
|
|
|
687
822
|
await meeting.startTranscription();
|
|
688
823
|
assert.equal(webex.internal.voicea.on.callCount, 4);
|
|
689
824
|
assert.equal(meeting.areVoiceaEventsSetup, true);
|
|
690
825
|
assert.equal(webex.internal.voicea.listenToEvents.callCount, 1);
|
|
691
|
-
assert.calledTwice(
|
|
692
|
-
|
|
693
|
-
);
|
|
694
|
-
assert.calledWith(
|
|
695
|
-
webex.internal.voicea.toggleTranscribing,
|
|
696
|
-
true,
|
|
697
|
-
);
|
|
826
|
+
assert.calledTwice(webex.internal.voicea.toggleTranscribing);
|
|
827
|
+
assert.calledWith(webex.internal.voicea.toggleTranscribing, true);
|
|
698
828
|
});
|
|
699
829
|
|
|
700
830
|
it('should listen to events and not toggleTranscribing if the user is not a host', async () => {
|
|
701
831
|
meeting.joinedWith = {
|
|
702
|
-
state: 'JOINED'
|
|
832
|
+
state: 'JOINED',
|
|
703
833
|
};
|
|
704
834
|
meeting.areVoiceaEventsSetup = false;
|
|
705
835
|
meeting.roles = ['COHOST'];
|
|
@@ -709,9 +839,7 @@ describe('plugin-meetings', () => {
|
|
|
709
839
|
assert.equal(webex.internal.voicea.on.callCount, 4);
|
|
710
840
|
assert.equal(meeting.areVoiceaEventsSetup, true);
|
|
711
841
|
assert.equal(webex.internal.voicea.listenToEvents.callCount, 1);
|
|
712
|
-
assert.notCalled(
|
|
713
|
-
webex.internal.voicea.toggleTranscribing
|
|
714
|
-
);
|
|
842
|
+
assert.notCalled(webex.internal.voicea.toggleTranscribing);
|
|
715
843
|
});
|
|
716
844
|
|
|
717
845
|
it("should throw error if request doesn't work", async () => {
|
|
@@ -752,7 +880,7 @@ describe('plugin-meetings', () => {
|
|
|
752
880
|
describe('#setCaptionLanguage', () => {
|
|
753
881
|
beforeEach(() => {
|
|
754
882
|
meeting.isTranscriptionSupported = sinon.stub();
|
|
755
|
-
meeting.transcription = {
|
|
883
|
+
meeting.transcription = {languageOptions: {}};
|
|
756
884
|
webex.internal.voicea.on = sinon.stub();
|
|
757
885
|
webex.internal.voicea.off = sinon.stub();
|
|
758
886
|
webex.internal.voicea.setCaptionLanguage = sinon.stub();
|
|
@@ -778,23 +906,23 @@ describe('plugin-meetings', () => {
|
|
|
778
906
|
const languageCode = 'fr';
|
|
779
907
|
|
|
780
908
|
meeting.setCaptionLanguage(languageCode).then((resolvedLanguageCode) => {
|
|
781
|
-
assert.calledWith(
|
|
782
|
-
|
|
909
|
+
assert.calledWith(webex.internal.voicea.requestLanguage, languageCode);
|
|
910
|
+
assert.equal(resolvedLanguageCode, languageCode);
|
|
911
|
+
assert.equal(
|
|
912
|
+
meeting.transcription.languageOptions.currentCaptionLanguage,
|
|
783
913
|
languageCode
|
|
784
914
|
);
|
|
785
|
-
assert.equal(resolvedLanguageCode, languageCode);
|
|
786
|
-
assert.equal(meeting.transcription.languageOptions.currentCaptionLanguage, languageCode);
|
|
787
915
|
done();
|
|
788
916
|
});
|
|
789
917
|
|
|
790
918
|
assert.calledOnceWithMatch(
|
|
791
919
|
webex.internal.voicea.on,
|
|
792
|
-
VOICEAEVENTS.CAPTION_LANGUAGE_UPDATE
|
|
920
|
+
VOICEAEVENTS.CAPTION_LANGUAGE_UPDATE
|
|
793
921
|
);
|
|
794
922
|
|
|
795
923
|
// Trigger the event
|
|
796
924
|
const voiceaListenerLangugeUpdate = webex.internal.voicea.on.getCall(0).args[1];
|
|
797
|
-
voiceaListenerLangugeUpdate({
|
|
925
|
+
voiceaListenerLangugeUpdate({statusCode: 200, languageCode});
|
|
798
926
|
});
|
|
799
927
|
|
|
800
928
|
it('should reject if the statusCode in payload is not 200', (done) => {
|
|
@@ -802,8 +930,8 @@ describe('plugin-meetings', () => {
|
|
|
802
930
|
const languageCode = 'fr';
|
|
803
931
|
const rejectPayload = {
|
|
804
932
|
statusCode: 400,
|
|
805
|
-
message: 'some error message'
|
|
806
|
-
}
|
|
933
|
+
message: 'some error message',
|
|
934
|
+
};
|
|
807
935
|
|
|
808
936
|
meeting.setCaptionLanguage(languageCode).catch((payload) => {
|
|
809
937
|
assert.equal(payload, rejectPayload);
|
|
@@ -812,20 +940,19 @@ describe('plugin-meetings', () => {
|
|
|
812
940
|
|
|
813
941
|
assert.calledOnceWithMatch(
|
|
814
942
|
webex.internal.voicea.on,
|
|
815
|
-
VOICEAEVENTS.CAPTION_LANGUAGE_UPDATE
|
|
943
|
+
VOICEAEVENTS.CAPTION_LANGUAGE_UPDATE
|
|
816
944
|
);
|
|
817
945
|
|
|
818
946
|
// Trigger the event
|
|
819
947
|
const voiceaListenerLangugeUpdate = webex.internal.voicea.on.getCall(0).args[1];
|
|
820
948
|
voiceaListenerLangugeUpdate(rejectPayload);
|
|
821
949
|
});
|
|
822
|
-
|
|
823
950
|
});
|
|
824
951
|
|
|
825
952
|
describe('#setSpokenLanguage', () => {
|
|
826
953
|
beforeEach(() => {
|
|
827
954
|
meeting.isTranscriptionSupported = sinon.stub();
|
|
828
|
-
meeting.transcription = {
|
|
955
|
+
meeting.transcription = {languageOptions: {}};
|
|
829
956
|
webex.internal.voicea.on = sinon.stub();
|
|
830
957
|
webex.internal.voicea.off = sinon.stub();
|
|
831
958
|
webex.internal.voicea.setSpokenLanguage = sinon.stub();
|
|
@@ -850,59 +977,48 @@ describe('plugin-meetings', () => {
|
|
|
850
977
|
const languageCode = 'fr';
|
|
851
978
|
|
|
852
979
|
meeting.setSpokenLanguage(languageCode).then((resolvedLanguageCode) => {
|
|
853
|
-
assert.calledWith(
|
|
854
|
-
webex.internal.voicea.setSpokenLanguage,
|
|
855
|
-
languageCode
|
|
856
|
-
);
|
|
980
|
+
assert.calledWith(webex.internal.voicea.setSpokenLanguage, languageCode);
|
|
857
981
|
assert.equal(resolvedLanguageCode, languageCode);
|
|
858
982
|
assert.equal(meeting.transcription.languageOptions.currentSpokenLanguage, languageCode);
|
|
859
983
|
done();
|
|
860
984
|
});
|
|
861
985
|
|
|
862
|
-
assert.calledOnceWithMatch(
|
|
863
|
-
webex.internal.voicea.on,
|
|
864
|
-
VOICEAEVENTS.SPOKEN_LANGUAGE_UPDATE,
|
|
865
|
-
);
|
|
986
|
+
assert.calledOnceWithMatch(webex.internal.voicea.on, VOICEAEVENTS.SPOKEN_LANGUAGE_UPDATE);
|
|
866
987
|
|
|
867
988
|
// Trigger the event
|
|
868
989
|
const voiceaListenerLangugeUpdate = webex.internal.voicea.on.getCall(0).args[1];
|
|
869
|
-
voiceaListenerLangugeUpdate({
|
|
990
|
+
voiceaListenerLangugeUpdate({languageCode});
|
|
870
991
|
});
|
|
871
992
|
|
|
872
993
|
it('should reject if the language code does not exist in payload', (done) => {
|
|
873
994
|
meeting.isTranscriptionSupported.returns(true);
|
|
874
995
|
const languageCode = 'fr';
|
|
875
996
|
const rejectPayload = {
|
|
876
|
-
|
|
877
|
-
}
|
|
997
|
+
message: 'some error message',
|
|
998
|
+
};
|
|
878
999
|
|
|
879
1000
|
meeting.setSpokenLanguage(languageCode).catch((payload) => {
|
|
880
1001
|
assert.equal(payload, rejectPayload);
|
|
881
1002
|
done();
|
|
882
1003
|
});
|
|
883
1004
|
|
|
884
|
-
assert.calledOnceWithMatch(
|
|
885
|
-
webex.internal.voicea.on,
|
|
886
|
-
VOICEAEVENTS.SPOKEN_LANGUAGE_UPDATE,
|
|
887
|
-
);
|
|
1005
|
+
assert.calledOnceWithMatch(webex.internal.voicea.on, VOICEAEVENTS.SPOKEN_LANGUAGE_UPDATE);
|
|
888
1006
|
|
|
889
1007
|
// Trigger the event
|
|
890
1008
|
const voiceaListenerLangugeUpdate = webex.internal.voicea.on.getCall(0).args[1];
|
|
891
1009
|
voiceaListenerLangugeUpdate(rejectPayload);
|
|
892
1010
|
});
|
|
893
|
-
|
|
894
1011
|
});
|
|
895
1012
|
|
|
896
1013
|
describe('transcription events', () => {
|
|
1014
|
+
beforeEach(() => {
|
|
1015
|
+
meeting.trigger = sinon.stub();
|
|
1016
|
+
});
|
|
1017
|
+
|
|
897
1018
|
it('should trigger meeting:caption-received event', () => {
|
|
898
1019
|
meeting.voiceaListenerCallbacks[VOICEAEVENTS.NEW_CAPTION]({});
|
|
899
1020
|
assert.calledWith(
|
|
900
|
-
|
|
901
|
-
sinon.match.instanceOf(Meeting),
|
|
902
|
-
{
|
|
903
|
-
file: 'meeting/index',
|
|
904
|
-
function: 'setUpVoiceaListeners',
|
|
905
|
-
},
|
|
1021
|
+
meeting.trigger,
|
|
906
1022
|
EVENT_TRIGGERS.MEETING_CAPTION_RECEIVED
|
|
907
1023
|
);
|
|
908
1024
|
});
|
|
@@ -910,12 +1026,7 @@ describe('plugin-meetings', () => {
|
|
|
910
1026
|
it('should trigger meeting:receiveTranscription:started event', () => {
|
|
911
1027
|
meeting.voiceaListenerCallbacks[VOICEAEVENTS.VOICEA_ANNOUNCEMENT]({});
|
|
912
1028
|
assert.calledWith(
|
|
913
|
-
|
|
914
|
-
sinon.match.instanceOf(Meeting),
|
|
915
|
-
{
|
|
916
|
-
file: 'meeting/index',
|
|
917
|
-
function: 'setUpVoiceaListeners',
|
|
918
|
-
},
|
|
1029
|
+
meeting.trigger,
|
|
919
1030
|
EVENT_TRIGGERS.MEETING_STARTED_RECEIVING_TRANSCRIPTION
|
|
920
1031
|
);
|
|
921
1032
|
});
|
|
@@ -923,12 +1034,7 @@ describe('plugin-meetings', () => {
|
|
|
923
1034
|
it('should trigger meeting:caption-received event', () => {
|
|
924
1035
|
meeting.voiceaListenerCallbacks[VOICEAEVENTS.NEW_CAPTION]({});
|
|
925
1036
|
assert.calledWith(
|
|
926
|
-
|
|
927
|
-
sinon.match.instanceOf(Meeting),
|
|
928
|
-
{
|
|
929
|
-
file: 'meeting/index',
|
|
930
|
-
function: 'setUpVoiceaListeners',
|
|
931
|
-
},
|
|
1037
|
+
meeting.trigger,
|
|
932
1038
|
EVENT_TRIGGERS.MEETING_CAPTION_RECEIVED
|
|
933
1039
|
);
|
|
934
1040
|
});
|
|
@@ -1134,7 +1240,7 @@ describe('plugin-meetings', () => {
|
|
|
1134
1240
|
file: 'meeting/index',
|
|
1135
1241
|
function: 'join',
|
|
1136
1242
|
},
|
|
1137
|
-
EVENT_TRIGGERS.MEETING_TRANSCRIPTION_CONNECTED
|
|
1243
|
+
EVENT_TRIGGERS.MEETING_TRANSCRIPTION_CONNECTED
|
|
1138
1244
|
);
|
|
1139
1245
|
});
|
|
1140
1246
|
|
|
@@ -1412,7 +1518,6 @@ describe('plugin-meetings', () => {
|
|
|
1412
1518
|
describe('#addMedia', () => {
|
|
1413
1519
|
const muteStateStub = {
|
|
1414
1520
|
handleClientRequest: sinon.stub().returns(Promise.resolve(true)),
|
|
1415
|
-
applyClientStateLocally: sinon.stub().returns(Promise.resolve(true)),
|
|
1416
1521
|
};
|
|
1417
1522
|
|
|
1418
1523
|
let fakeMediaConnection;
|
|
@@ -2506,6 +2611,7 @@ describe('plugin-meetings', () => {
|
|
|
2506
2611
|
|
|
2507
2612
|
beforeEach(async () => {
|
|
2508
2613
|
meeting.meetingState = 'ACTIVE';
|
|
2614
|
+
meeting.remoteShareInstanceId = '1234';
|
|
2509
2615
|
prevConfigValue = meeting.config.stats.enableStatsAnalyzer;
|
|
2510
2616
|
|
|
2511
2617
|
meeting.config.stats.enableStatsAnalyzer = true;
|
|
@@ -2611,6 +2717,66 @@ describe('plugin-meetings', () => {
|
|
|
2611
2717
|
});
|
|
2612
2718
|
});
|
|
2613
2719
|
|
|
2720
|
+
it('REMOTE_MEDIA_STARTED triggers "meeting:media:remote:start" event and sends metrics for share', async () => {
|
|
2721
|
+
statsAnalyzerStub.emit(
|
|
2722
|
+
{file: 'test', function: 'test'},
|
|
2723
|
+
StatsAnalyzerModule.EVENTS.REMOTE_MEDIA_STARTED,
|
|
2724
|
+
{type: 'share'}
|
|
2725
|
+
);
|
|
2726
|
+
|
|
2727
|
+
assert.calledWith(
|
|
2728
|
+
TriggerProxy.trigger,
|
|
2729
|
+
sinon.match.instanceOf(Meeting),
|
|
2730
|
+
{
|
|
2731
|
+
file: 'meeting/index',
|
|
2732
|
+
function: 'addMedia',
|
|
2733
|
+
},
|
|
2734
|
+
EVENT_TRIGGERS.MEETING_MEDIA_REMOTE_STARTED,
|
|
2735
|
+
{
|
|
2736
|
+
type: 'share',
|
|
2737
|
+
}
|
|
2738
|
+
);
|
|
2739
|
+
assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
|
|
2740
|
+
name: 'client.media.rx.start',
|
|
2741
|
+
payload: {mediaType: 'share', shareInstanceId: meeting.remoteShareInstanceId},
|
|
2742
|
+
options: {
|
|
2743
|
+
meetingId: meeting.id,
|
|
2744
|
+
},
|
|
2745
|
+
});
|
|
2746
|
+
|
|
2747
|
+
assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
|
|
2748
|
+
name: 'client.media.render.start',
|
|
2749
|
+
payload: {mediaType: 'share', shareInstanceId: meeting.remoteShareInstanceId},
|
|
2750
|
+
options: {
|
|
2751
|
+
meetingId: meeting.id,
|
|
2752
|
+
},
|
|
2753
|
+
});
|
|
2754
|
+
});
|
|
2755
|
+
|
|
2756
|
+
it('REMOTE_MEDIA_STOPPED triggers the right metrics for share', async () => {
|
|
2757
|
+
statsAnalyzerStub.emit(
|
|
2758
|
+
{file: 'test', function: 'test'},
|
|
2759
|
+
StatsAnalyzerModule.EVENTS.REMOTE_MEDIA_STOPPED,
|
|
2760
|
+
{type: 'share'}
|
|
2761
|
+
);
|
|
2762
|
+
|
|
2763
|
+
assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
|
|
2764
|
+
name: 'client.media.rx.stop',
|
|
2765
|
+
payload: {mediaType: 'share', shareInstanceId: meeting.remoteShareInstanceId},
|
|
2766
|
+
options: {
|
|
2767
|
+
meetingId: meeting.id,
|
|
2768
|
+
},
|
|
2769
|
+
});
|
|
2770
|
+
|
|
2771
|
+
assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
|
|
2772
|
+
name: 'client.media.render.stop',
|
|
2773
|
+
payload: {mediaType: 'share', shareInstanceId: meeting.remoteShareInstanceId},
|
|
2774
|
+
options: {
|
|
2775
|
+
meetingId: meeting.id,
|
|
2776
|
+
},
|
|
2777
|
+
});
|
|
2778
|
+
});
|
|
2779
|
+
|
|
2614
2780
|
it('calls submitMQE correctly', async () => {
|
|
2615
2781
|
const fakeData = {intervalMetadata: {bla: 'bla'}};
|
|
2616
2782
|
|
|
@@ -2855,9 +3021,10 @@ describe('plugin-meetings', () => {
|
|
|
2855
3021
|
meeting.setMercuryListener = sinon.stub();
|
|
2856
3022
|
meeting.locusInfo.onFullLocus = sinon.stub();
|
|
2857
3023
|
meeting.webex.meetings.geoHintInfo = {regionCode: 'EU', countryCode: 'UK'};
|
|
2858
|
-
meeting.roap.doTurnDiscovery = sinon
|
|
2859
|
-
|
|
2860
|
-
|
|
3024
|
+
meeting.roap.doTurnDiscovery = sinon.stub().resolves({
|
|
3025
|
+
turnServerInfo: {url: 'turn-url', username: 'turn user', password: 'turn password'},
|
|
3026
|
+
turnDiscoverySkippedReason: 'reachability',
|
|
3027
|
+
});
|
|
2861
3028
|
meeting.deferSDPAnswer = new Defer();
|
|
2862
3029
|
meeting.deferSDPAnswer.resolve();
|
|
2863
3030
|
meeting.webex.meetings.meetingCollection = new MeetingCollection();
|
|
@@ -2868,7 +3035,7 @@ describe('plugin-meetings', () => {
|
|
|
2868
3035
|
// setup things that are expected to be the same across all the tests and are actually irrelevant for these tests
|
|
2869
3036
|
expectedDebugId = `MC-${meeting.id.substring(0, 4)}`;
|
|
2870
3037
|
expectedMediaConnectionConfig = {
|
|
2871
|
-
iceServers: [{urls:
|
|
3038
|
+
iceServers: [{urls: 'turn-url', username: 'turn user', credential: 'turn password'}],
|
|
2872
3039
|
skipInactiveTransceivers: false,
|
|
2873
3040
|
requireH264: true,
|
|
2874
3041
|
sdpMunging: {
|
|
@@ -2892,9 +3059,13 @@ describe('plugin-meetings', () => {
|
|
|
2892
3059
|
getSettings: sinon.stub().returns({
|
|
2893
3060
|
deviceId: 'some device id',
|
|
2894
3061
|
}),
|
|
2895
|
-
|
|
3062
|
+
userMuted: false,
|
|
3063
|
+
systemMuted: false,
|
|
3064
|
+
get muted() {
|
|
3065
|
+
return this.userMuted || this.systemMuted;
|
|
3066
|
+
},
|
|
2896
3067
|
setUnmuteAllowed: sinon.stub(),
|
|
2897
|
-
|
|
3068
|
+
setUserMuted: sinon.stub(),
|
|
2898
3069
|
setServerMuted: sinon.stub(),
|
|
2899
3070
|
outputStream: {
|
|
2900
3071
|
getTracks: () => {
|
|
@@ -2927,6 +3098,7 @@ describe('plugin-meetings', () => {
|
|
|
2927
3098
|
createSendSlot: sinon.stub().returns({
|
|
2928
3099
|
publishStream: sinon.stub(),
|
|
2929
3100
|
unpublishStream: sinon.stub(),
|
|
3101
|
+
setNamedMediaGroups: sinon.stub(),
|
|
2930
3102
|
}),
|
|
2931
3103
|
enableMultistreamAudio: sinon.stub(),
|
|
2932
3104
|
};
|
|
@@ -3128,28 +3300,52 @@ describe('plugin-meetings', () => {
|
|
|
3128
3300
|
if (stream !== undefined) {
|
|
3129
3301
|
switch (type) {
|
|
3130
3302
|
case 'audio':
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3303
|
+
if (stream?.readyState === 'ended') {
|
|
3304
|
+
assert.notCalled(
|
|
3305
|
+
meeting.sendSlotManager.getSlot(MediaType.AudioMain).publishStream
|
|
3306
|
+
);
|
|
3307
|
+
} else {
|
|
3308
|
+
assert.calledOnceWithExactly(
|
|
3309
|
+
meeting.sendSlotManager.getSlot(MediaType.AudioMain).publishStream,
|
|
3310
|
+
stream
|
|
3311
|
+
);
|
|
3312
|
+
}
|
|
3135
3313
|
break;
|
|
3136
3314
|
case 'video':
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3315
|
+
if (stream?.readyState === 'ended') {
|
|
3316
|
+
assert.notCalled(
|
|
3317
|
+
meeting.sendSlotManager.getSlot(MediaType.VideoMain).publishStream
|
|
3318
|
+
);
|
|
3319
|
+
} else {
|
|
3320
|
+
assert.calledOnceWithExactly(
|
|
3321
|
+
meeting.sendSlotManager.getSlot(MediaType.VideoMain).publishStream,
|
|
3322
|
+
stream
|
|
3323
|
+
);
|
|
3324
|
+
}
|
|
3141
3325
|
break;
|
|
3142
3326
|
case 'screenShareAudio':
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3327
|
+
if (stream?.readyState === 'ended') {
|
|
3328
|
+
assert.notCalled(
|
|
3329
|
+
meeting.sendSlotManager.getSlot(MediaType.AudioSlides).publishStream
|
|
3330
|
+
);
|
|
3331
|
+
} else {
|
|
3332
|
+
assert.calledOnceWithExactly(
|
|
3333
|
+
meeting.sendSlotManager.getSlot(MediaType.AudioSlides).publishStream,
|
|
3334
|
+
stream
|
|
3335
|
+
);
|
|
3336
|
+
}
|
|
3147
3337
|
break;
|
|
3148
3338
|
case 'screenShareVideo':
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3339
|
+
if (stream?.readyState === 'ended') {
|
|
3340
|
+
assert.notCalled(
|
|
3341
|
+
meeting.sendSlotManager.getSlot(MediaType.VideoSlides).publishStream
|
|
3342
|
+
);
|
|
3343
|
+
} else {
|
|
3344
|
+
assert.calledOnceWithExactly(
|
|
3345
|
+
meeting.sendSlotManager.getSlot(MediaType.VideoSlides).publishStream,
|
|
3346
|
+
stream
|
|
3347
|
+
);
|
|
3348
|
+
}
|
|
3153
3349
|
break;
|
|
3154
3350
|
}
|
|
3155
3351
|
}
|
|
@@ -3177,7 +3373,7 @@ describe('plugin-meetings', () => {
|
|
|
3177
3373
|
}
|
|
3178
3374
|
};
|
|
3179
3375
|
|
|
3180
|
-
it('addMedia() works correctly when media is enabled without
|
|
3376
|
+
it('addMedia() works correctly when media is enabled without streams to publish', async () => {
|
|
3181
3377
|
await meeting.addMedia();
|
|
3182
3378
|
await simulateRoapOffer();
|
|
3183
3379
|
await simulateRoapOk();
|
|
@@ -3211,6 +3407,7 @@ describe('plugin-meetings', () => {
|
|
|
3211
3407
|
});
|
|
3212
3408
|
|
|
3213
3409
|
it('addMedia() works correctly when media is enabled with streams to publish', async () => {
|
|
3410
|
+
const handleDeviceLoggingSpy = sinon.spy(Meeting, 'handleDeviceLogging');
|
|
3214
3411
|
await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
|
|
3215
3412
|
await simulateRoapOffer();
|
|
3216
3413
|
await simulateRoapOk();
|
|
@@ -3241,10 +3438,82 @@ describe('plugin-meetings', () => {
|
|
|
3241
3438
|
|
|
3242
3439
|
// and that these were the only /media requests that were sent
|
|
3243
3440
|
assert.calledTwice(locusMediaRequestStub);
|
|
3441
|
+
|
|
3442
|
+
assert.calledOnce(handleDeviceLoggingSpy);
|
|
3443
|
+
});
|
|
3444
|
+
|
|
3445
|
+
it('addMedia() works correctly when media is enabled with streams to publish and stream is user muted', async () => {
|
|
3446
|
+
const handleDeviceLoggingSpy = sinon.spy(Meeting, 'handleDeviceLogging');
|
|
3447
|
+
fakeMicrophoneStream.userMuted = true;
|
|
3448
|
+
|
|
3449
|
+
await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
|
|
3450
|
+
await simulateRoapOffer();
|
|
3451
|
+
await simulateRoapOk();
|
|
3452
|
+
|
|
3453
|
+
// check RoapMediaConnection was created correctly
|
|
3454
|
+
checkMediaConnectionCreated({
|
|
3455
|
+
mediaConnectionConfig: expectedMediaConnectionConfig,
|
|
3456
|
+
localStreams: {
|
|
3457
|
+
audio: fakeMicrophoneStream,
|
|
3458
|
+
video: undefined,
|
|
3459
|
+
screenShareVideo: undefined,
|
|
3460
|
+
screenShareAudio: undefined,
|
|
3461
|
+
},
|
|
3462
|
+
direction: {
|
|
3463
|
+
audio: 'sendrecv',
|
|
3464
|
+
video: 'sendrecv',
|
|
3465
|
+
screenShare: 'recvonly',
|
|
3466
|
+
},
|
|
3467
|
+
remoteQualityLevel: 'HIGH',
|
|
3468
|
+
expectedDebugId,
|
|
3469
|
+
meetingId: meeting.id,
|
|
3470
|
+
});
|
|
3471
|
+
// and SDP offer was sent with the right audioMuted/videoMuted values
|
|
3472
|
+
checkSdpOfferSent({audioMuted: true, videoMuted: true});
|
|
3473
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
3474
|
+
checkOkSent({audioMuted: true, videoMuted: true});
|
|
3475
|
+
|
|
3476
|
+
// and that these were the only /media requests that were sent
|
|
3477
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
3478
|
+
assert.calledOnce(handleDeviceLoggingSpy);
|
|
3244
3479
|
});
|
|
3245
3480
|
|
|
3246
|
-
it('addMedia() works correctly when media is enabled with tracks to publish and track is
|
|
3247
|
-
fakeMicrophoneStream.
|
|
3481
|
+
it('addMedia() works correctly when media is enabled with tracks to publish and track is ended', async () => {
|
|
3482
|
+
fakeMicrophoneStream.readyState = 'ended';
|
|
3483
|
+
|
|
3484
|
+
await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
|
|
3485
|
+
await simulateRoapOffer();
|
|
3486
|
+
await simulateRoapOk();
|
|
3487
|
+
|
|
3488
|
+
// check RoapMediaConnection was created correctly
|
|
3489
|
+
checkMediaConnectionCreated({
|
|
3490
|
+
mediaConnectionConfig: expectedMediaConnectionConfig,
|
|
3491
|
+
localStreams: {
|
|
3492
|
+
audio: undefined,
|
|
3493
|
+
video: undefined,
|
|
3494
|
+
screenShareVideo: undefined,
|
|
3495
|
+
screenShareAudio: undefined,
|
|
3496
|
+
},
|
|
3497
|
+
direction: {
|
|
3498
|
+
audio: 'sendrecv',
|
|
3499
|
+
video: 'sendrecv',
|
|
3500
|
+
screenShare: 'recvonly',
|
|
3501
|
+
},
|
|
3502
|
+
remoteQualityLevel: 'HIGH',
|
|
3503
|
+
expectedDebugId,
|
|
3504
|
+
meetingId: meeting.id,
|
|
3505
|
+
});
|
|
3506
|
+
// and SDP offer was sent with the right audioMuted/videoMuted values
|
|
3507
|
+
checkSdpOfferSent({audioMuted: true, videoMuted: true});
|
|
3508
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
3509
|
+
checkOkSent({audioMuted: true, videoMuted: true});
|
|
3510
|
+
|
|
3511
|
+
// and that these were the only /media requests that were sent
|
|
3512
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
3513
|
+
});
|
|
3514
|
+
|
|
3515
|
+
it('addMedia() works correctly when media is enabled with streams to publish and stream is system muted', async () => {
|
|
3516
|
+
fakeMicrophoneStream.systemMuted = true;
|
|
3248
3517
|
|
|
3249
3518
|
await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
|
|
3250
3519
|
await simulateRoapOffer();
|
|
@@ -3277,7 +3546,8 @@ describe('plugin-meetings', () => {
|
|
|
3277
3546
|
assert.calledTwice(locusMediaRequestStub);
|
|
3278
3547
|
});
|
|
3279
3548
|
|
|
3280
|
-
it('addMedia() works correctly when media is disabled with
|
|
3549
|
+
it('addMedia() works correctly when media is disabled with streams to publish', async () => {
|
|
3550
|
+
const handleDeviceLoggingSpy = sinon.spy(Meeting, 'handleDeviceLogging');
|
|
3281
3551
|
await meeting.addMedia({
|
|
3282
3552
|
localStreams: {microphone: fakeMicrophoneStream},
|
|
3283
3553
|
audioEnabled: false,
|
|
@@ -3311,9 +3581,23 @@ describe('plugin-meetings', () => {
|
|
|
3311
3581
|
|
|
3312
3582
|
// and that these were the only /media requests that were sent
|
|
3313
3583
|
assert.calledTwice(locusMediaRequestStub);
|
|
3584
|
+
assert.calledOnce(handleDeviceLoggingSpy);
|
|
3314
3585
|
});
|
|
3315
3586
|
|
|
3316
|
-
it('
|
|
3587
|
+
it('handleDeviceLogging not called when media is disabled', async () => {
|
|
3588
|
+
const handleDeviceLoggingSpy = sinon.spy(Meeting, 'handleDeviceLogging');
|
|
3589
|
+
await meeting.addMedia({
|
|
3590
|
+
localStreams: {microphone: fakeMicrophoneStream},
|
|
3591
|
+
audioEnabled: false,
|
|
3592
|
+
videoEnabled: false
|
|
3593
|
+
});
|
|
3594
|
+
await simulateRoapOffer();
|
|
3595
|
+
await simulateRoapOk();
|
|
3596
|
+
|
|
3597
|
+
assert.notCalled(handleDeviceLoggingSpy);
|
|
3598
|
+
})
|
|
3599
|
+
|
|
3600
|
+
it('addMedia() works correctly when media is disabled with no streams to publish', async () => {
|
|
3317
3601
|
await meeting.addMedia({audioEnabled: false});
|
|
3318
3602
|
await simulateRoapOffer();
|
|
3319
3603
|
await simulateRoapOk();
|
|
@@ -3346,7 +3630,7 @@ describe('plugin-meetings', () => {
|
|
|
3346
3630
|
assert.calledTwice(locusMediaRequestStub);
|
|
3347
3631
|
});
|
|
3348
3632
|
|
|
3349
|
-
it('addMedia() works correctly when video is disabled with no
|
|
3633
|
+
it('addMedia() works correctly when video is disabled with no streams to publish', async () => {
|
|
3350
3634
|
await meeting.addMedia({videoEnabled: false});
|
|
3351
3635
|
await simulateRoapOffer();
|
|
3352
3636
|
await simulateRoapOk();
|
|
@@ -3379,7 +3663,7 @@ describe('plugin-meetings', () => {
|
|
|
3379
3663
|
assert.calledTwice(locusMediaRequestStub);
|
|
3380
3664
|
});
|
|
3381
3665
|
|
|
3382
|
-
it('addMedia() works correctly when screen share is disabled with no
|
|
3666
|
+
it('addMedia() works correctly when screen share is disabled with no streams to publish', async () => {
|
|
3383
3667
|
await meeting.addMedia({shareAudioEnabled: false, shareVideoEnabled: false});
|
|
3384
3668
|
await simulateRoapOffer();
|
|
3385
3669
|
await simulateRoapOk();
|
|
@@ -3480,9 +3764,13 @@ describe('plugin-meetings', () => {
|
|
|
3480
3764
|
const fakeMicrophoneStream2 = {
|
|
3481
3765
|
on: sinon.stub(),
|
|
3482
3766
|
off: sinon.stub(),
|
|
3483
|
-
|
|
3767
|
+
userMuted: false,
|
|
3768
|
+
systemMuted: false,
|
|
3769
|
+
get muted() {
|
|
3770
|
+
return this.userMuted || this.systemMuted;
|
|
3771
|
+
},
|
|
3484
3772
|
setUnmuteAllowed: sinon.stub(),
|
|
3485
|
-
|
|
3773
|
+
setUserMuted: sinon.stub(),
|
|
3486
3774
|
outputStream: {
|
|
3487
3775
|
getTracks: () => {
|
|
3488
3776
|
return [
|
|
@@ -3719,12 +4007,55 @@ describe('plugin-meetings', () => {
|
|
|
3719
4007
|
});
|
|
3720
4008
|
|
|
3721
4009
|
[
|
|
3722
|
-
{mute: true, title: 'muting a track before confluence is created'},
|
|
3723
|
-
{mute: false, title: 'unmuting a track before confluence is created'},
|
|
4010
|
+
{mute: true, title: 'user muting a track before confluence is created'},
|
|
4011
|
+
{mute: false, title: 'user unmuting a track before confluence is created'},
|
|
4012
|
+
].forEach(({mute, title}) =>
|
|
4013
|
+
it(title, async () => {
|
|
4014
|
+
// initialize the microphone mute state to opposite of what we do in the test
|
|
4015
|
+
fakeMicrophoneStream.userMuted = !mute;
|
|
4016
|
+
|
|
4017
|
+
await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
|
|
4018
|
+
await stableState();
|
|
4019
|
+
|
|
4020
|
+
resetHistory();
|
|
4021
|
+
|
|
4022
|
+
assert.equal(
|
|
4023
|
+
fakeMicrophoneStream.on.getCall(0).args[0],
|
|
4024
|
+
LocalStreamEventNames.UserMuteStateChange
|
|
4025
|
+
);
|
|
4026
|
+
const mutedListener = fakeMicrophoneStream.on.getCall(0).args[1];
|
|
4027
|
+
// simulate track being muted
|
|
4028
|
+
fakeMicrophoneStream.userMuted = mute;
|
|
4029
|
+
mutedListener(mute);
|
|
4030
|
+
|
|
4031
|
+
await stableState();
|
|
4032
|
+
|
|
4033
|
+
// nothing should happen
|
|
4034
|
+
assert.notCalled(locusMediaRequestStub);
|
|
4035
|
+
assert.notCalled(fakeRoapMediaConnection.update);
|
|
4036
|
+
|
|
4037
|
+
// now simulate roap offer and ok
|
|
4038
|
+
await simulateRoapOffer();
|
|
4039
|
+
await simulateRoapOk();
|
|
4040
|
+
|
|
4041
|
+
// it should be sent with the right mute status
|
|
4042
|
+
checkSdpOfferSent({audioMuted: mute, videoMuted: true});
|
|
4043
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
4044
|
+
checkOkSent({audioMuted: mute, videoMuted: true});
|
|
4045
|
+
|
|
4046
|
+
// nothing else should happen
|
|
4047
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
4048
|
+
assert.notCalled(fakeRoapMediaConnection.update);
|
|
4049
|
+
})
|
|
4050
|
+
);
|
|
4051
|
+
|
|
4052
|
+
[
|
|
4053
|
+
{mute: true, title: 'system muting a track before confluence is created'},
|
|
4054
|
+
{mute: false, title: 'system unmuting a track before confluence is created'},
|
|
3724
4055
|
].forEach(({mute, title}) =>
|
|
3725
4056
|
it(title, async () => {
|
|
3726
4057
|
// initialize the microphone mute state to opposite of what we do in the test
|
|
3727
|
-
fakeMicrophoneStream.
|
|
4058
|
+
fakeMicrophoneStream.systemMuted = !mute;
|
|
3728
4059
|
|
|
3729
4060
|
await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
|
|
3730
4061
|
await stableState();
|
|
@@ -3733,10 +4064,11 @@ describe('plugin-meetings', () => {
|
|
|
3733
4064
|
|
|
3734
4065
|
assert.equal(
|
|
3735
4066
|
fakeMicrophoneStream.on.getCall(0).args[0],
|
|
3736
|
-
|
|
4067
|
+
LocalStreamEventNames.UserMuteStateChange
|
|
3737
4068
|
);
|
|
3738
4069
|
const mutedListener = fakeMicrophoneStream.on.getCall(0).args[1];
|
|
3739
4070
|
// simulate track being muted
|
|
4071
|
+
fakeMicrophoneStream.systemMuted = mute;
|
|
3740
4072
|
mutedListener(mute);
|
|
3741
4073
|
|
|
3742
4074
|
await stableState();
|
|
@@ -6137,6 +6469,65 @@ describe('plugin-meetings', () => {
|
|
|
6137
6469
|
checkScreenShareVideoPublished(videoShareStream);
|
|
6138
6470
|
checkScreenShareAudioPublished(audioShareStream);
|
|
6139
6471
|
});
|
|
6472
|
+
|
|
6473
|
+
[
|
|
6474
|
+
{
|
|
6475
|
+
endedStream: 'microphone',
|
|
6476
|
+
streams: {
|
|
6477
|
+
microphone: {
|
|
6478
|
+
readyState: 'ended',
|
|
6479
|
+
},
|
|
6480
|
+
camera: undefined,
|
|
6481
|
+
screenShare: {
|
|
6482
|
+
audio: undefined,
|
|
6483
|
+
video: undefined,
|
|
6484
|
+
},
|
|
6485
|
+
},
|
|
6486
|
+
},
|
|
6487
|
+
{
|
|
6488
|
+
endedStream: 'camera',
|
|
6489
|
+
streams: {
|
|
6490
|
+
microphone: undefined,
|
|
6491
|
+
camera: {
|
|
6492
|
+
readyState: 'ended',
|
|
6493
|
+
},
|
|
6494
|
+
screenShare: {
|
|
6495
|
+
audio: undefined,
|
|
6496
|
+
video: undefined,
|
|
6497
|
+
},
|
|
6498
|
+
},
|
|
6499
|
+
},
|
|
6500
|
+
{
|
|
6501
|
+
endedStream: 'screenShare audio',
|
|
6502
|
+
streams: {
|
|
6503
|
+
microphone: undefined,
|
|
6504
|
+
camera: undefined,
|
|
6505
|
+
screenShare: {
|
|
6506
|
+
audio: {
|
|
6507
|
+
readyState: 'ended',
|
|
6508
|
+
},
|
|
6509
|
+
video: undefined,
|
|
6510
|
+
},
|
|
6511
|
+
},
|
|
6512
|
+
},
|
|
6513
|
+
{
|
|
6514
|
+
endedStream: 'screenShare video',
|
|
6515
|
+
streams: {
|
|
6516
|
+
microphone: undefined,
|
|
6517
|
+
camera: undefined,
|
|
6518
|
+
screenShare: {
|
|
6519
|
+
audio: undefined,
|
|
6520
|
+
video: {
|
|
6521
|
+
readyState: 'ended',
|
|
6522
|
+
},
|
|
6523
|
+
},
|
|
6524
|
+
},
|
|
6525
|
+
},
|
|
6526
|
+
].forEach(({endedStream, streams}) => {
|
|
6527
|
+
it(`throws error if readyState of ${endedStream} is ended`, async () => {
|
|
6528
|
+
assert.isRejected(meeting.publishStreams(streams));
|
|
6529
|
+
});
|
|
6530
|
+
});
|
|
6140
6531
|
});
|
|
6141
6532
|
|
|
6142
6533
|
describe('unpublishStreams', () => {
|
|
@@ -6266,6 +6657,31 @@ describe('plugin-meetings', () => {
|
|
|
6266
6657
|
});
|
|
6267
6658
|
});
|
|
6268
6659
|
|
|
6660
|
+
describe('#setSendNamedMediaGroup', () => {
|
|
6661
|
+
beforeEach(() => {
|
|
6662
|
+
meeting.sendSlotManager.setNamedMediaGroups = sinon.stub().returns(undefined);
|
|
6663
|
+
});
|
|
6664
|
+
it('should throw error if not audio type', () => {
|
|
6665
|
+
expect(() => meeting.setSendNamedMediaGroup(MediaType.VideoMain, 20)).to.throw(
|
|
6666
|
+
`cannot set send named media group which media type is ${MediaType.VideoMain}`
|
|
6667
|
+
);
|
|
6668
|
+
});
|
|
6669
|
+
it('fails if there is no media connection', () => {
|
|
6670
|
+
meeting.mediaProperties.webrtcMediaConnection = undefined;
|
|
6671
|
+
meeting.setSendNamedMediaGroup('AUDIO-MAIN', 20);
|
|
6672
|
+
assert.notCalled(meeting.sendSlotManager.setNamedMediaGroups);
|
|
6673
|
+
});
|
|
6674
|
+
|
|
6675
|
+
it('success if there is media connection', () => {
|
|
6676
|
+
meeting.isMultistream = true;
|
|
6677
|
+
meeting.mediaProperties.webrtcMediaConnection = true;
|
|
6678
|
+
meeting.setSendNamedMediaGroup('AUDIO-MAIN', 20);
|
|
6679
|
+
assert.calledOnceWithExactly(meeting.sendSlotManager.setNamedMediaGroups, 'AUDIO-MAIN', [
|
|
6680
|
+
{type: 1, value: 20},
|
|
6681
|
+
]);
|
|
6682
|
+
});
|
|
6683
|
+
});
|
|
6684
|
+
|
|
6269
6685
|
describe('#enableMusicMode', () => {
|
|
6270
6686
|
beforeEach(() => {
|
|
6271
6687
|
meeting.isMultistream = true;
|
|
@@ -7336,6 +7752,7 @@ describe('plugin-meetings', () => {
|
|
|
7336
7752
|
});
|
|
7337
7753
|
it('listens to the self admitted guest event', (done) => {
|
|
7338
7754
|
meeting.stopKeepAlive = sinon.stub();
|
|
7755
|
+
meeting.updateLLMConnection = sinon.stub();
|
|
7339
7756
|
meeting.locusInfo.emit({function: 'test', file: 'test'}, 'SELF_ADMITTED_GUEST', test1);
|
|
7340
7757
|
assert.calledOnceWithExactly(meeting.stopKeepAlive);
|
|
7341
7758
|
assert.calledThrice(TriggerProxy.trigger);
|
|
@@ -7346,6 +7763,7 @@ describe('plugin-meetings', () => {
|
|
|
7346
7763
|
'meeting:self:guestAdmitted',
|
|
7347
7764
|
{payload: test1}
|
|
7348
7765
|
);
|
|
7766
|
+
assert.calledOnce(meeting.updateLLMConnection);
|
|
7349
7767
|
done();
|
|
7350
7768
|
});
|
|
7351
7769
|
|
|
@@ -8267,6 +8685,34 @@ describe('plugin-meetings', () => {
|
|
|
8267
8685
|
|
|
8268
8686
|
checkParseMeetingInfo(expectedInfoToParse);
|
|
8269
8687
|
});
|
|
8688
|
+
|
|
8689
|
+
it('should parse meeting info, set values, and return null when permissionToken is not present', () => {
|
|
8690
|
+
meeting.config.experimental = {enableMediaNegotiatedEvent: true};
|
|
8691
|
+
meeting.config.experimental.enableUnifiedMeetings = true;
|
|
8692
|
+
const FAKE_STRING_DESTINATION = 'sipUrl';
|
|
8693
|
+
const FAKE_MEETING_INFO = {
|
|
8694
|
+
conversationUrl: uuid1,
|
|
8695
|
+
locusUrl: url1,
|
|
8696
|
+
meetingJoinUrl: url2,
|
|
8697
|
+
meetingNumber: '12345',
|
|
8698
|
+
sipMeetingUri: test1,
|
|
8699
|
+
sipUrl: test1,
|
|
8700
|
+
owner: test2,
|
|
8701
|
+
};
|
|
8702
|
+
|
|
8703
|
+
meeting.parseMeetingInfo(FAKE_MEETING_INFO, FAKE_STRING_DESTINATION);
|
|
8704
|
+
const expectedInfoToParse = {
|
|
8705
|
+
conversationUrl: uuid1,
|
|
8706
|
+
locusUrl: url1,
|
|
8707
|
+
sipUri: test1,
|
|
8708
|
+
meetingNumber: '12345',
|
|
8709
|
+
meetingJoinUrl: url2,
|
|
8710
|
+
owner: test2,
|
|
8711
|
+
};
|
|
8712
|
+
|
|
8713
|
+
checkParseMeetingInfo(expectedInfoToParse);
|
|
8714
|
+
});
|
|
8715
|
+
|
|
8270
8716
|
it('should parse interpretation info correctly', () => {
|
|
8271
8717
|
const parseInterpretationInfo = sinon.spy(MeetingUtil, 'parseInterpretationInfo');
|
|
8272
8718
|
const mockToggleOnData = {
|
|
@@ -9403,9 +9849,16 @@ describe('plugin-meetings', () => {
|
|
|
9403
9849
|
it('check triggerAnnotationInfoEvent event', () => {
|
|
9404
9850
|
TriggerProxy.trigger.reset();
|
|
9405
9851
|
const annotationInfo = {version: '1', policy: 'Approval'};
|
|
9406
|
-
const expectAnnotationInfo = {
|
|
9852
|
+
const expectAnnotationInfo = {
|
|
9853
|
+
annotationInfo,
|
|
9854
|
+
meetingId: meeting.id,
|
|
9855
|
+
resourceType: 'FILE',
|
|
9856
|
+
};
|
|
9407
9857
|
meeting.webex.meetings = {};
|
|
9408
|
-
meeting.triggerAnnotationInfoEvent(
|
|
9858
|
+
meeting.triggerAnnotationInfoEvent(
|
|
9859
|
+
{annotation: annotationInfo, resourceType: 'FILE'},
|
|
9860
|
+
{}
|
|
9861
|
+
);
|
|
9409
9862
|
assert.calledWith(
|
|
9410
9863
|
TriggerProxy.trigger,
|
|
9411
9864
|
{},
|
|
@@ -9419,8 +9872,8 @@ describe('plugin-meetings', () => {
|
|
|
9419
9872
|
|
|
9420
9873
|
TriggerProxy.trigger.reset();
|
|
9421
9874
|
meeting.triggerAnnotationInfoEvent(
|
|
9422
|
-
{annotation: annotationInfo},
|
|
9423
|
-
{annotation: annotationInfo}
|
|
9875
|
+
{annotation: annotationInfo, resourceType: 'FILE'},
|
|
9876
|
+
{annotation: annotationInfo, resourceType: 'FILE'}
|
|
9424
9877
|
);
|
|
9425
9878
|
assert.notCalled(TriggerProxy.trigger);
|
|
9426
9879
|
|
|
@@ -9429,10 +9882,11 @@ describe('plugin-meetings', () => {
|
|
|
9429
9882
|
const expectAnnotationInfoUpdated = {
|
|
9430
9883
|
annotationInfo: annotationInfoUpdate,
|
|
9431
9884
|
meetingId: meeting.id,
|
|
9885
|
+
resourceType: 'FILE',
|
|
9432
9886
|
};
|
|
9433
9887
|
meeting.triggerAnnotationInfoEvent(
|
|
9434
|
-
{annotation: annotationInfoUpdate},
|
|
9435
|
-
{annotation: annotationInfo}
|
|
9888
|
+
{annotation: annotationInfoUpdate, resourceType: 'FILE'},
|
|
9889
|
+
{annotation: annotationInfo, resourceType: 'FILE'}
|
|
9436
9890
|
);
|
|
9437
9891
|
assert.calledWith(
|
|
9438
9892
|
TriggerProxy.trigger,
|
|
@@ -9446,7 +9900,10 @@ describe('plugin-meetings', () => {
|
|
|
9446
9900
|
);
|
|
9447
9901
|
|
|
9448
9902
|
TriggerProxy.trigger.reset();
|
|
9449
|
-
meeting.triggerAnnotationInfoEvent(null, {
|
|
9903
|
+
meeting.triggerAnnotationInfoEvent(null, {
|
|
9904
|
+
annotation: annotationInfoUpdate,
|
|
9905
|
+
resourceType: 'FILE',
|
|
9906
|
+
});
|
|
9450
9907
|
assert.notCalled(TriggerProxy.trigger);
|
|
9451
9908
|
});
|
|
9452
9909
|
});
|
|
@@ -9470,6 +9927,11 @@ describe('plugin-meetings', () => {
|
|
|
9470
9927
|
'https://board-a.wbx2.com/board/api/v1/channels/977a7330-54f4-11eb-b1ef-91f5eefc7bf3',
|
|
9471
9928
|
};
|
|
9472
9929
|
|
|
9930
|
+
const SHARE_TYPE = {
|
|
9931
|
+
FILE: 'FILE',
|
|
9932
|
+
DESKTOP: 'DESKTOP',
|
|
9933
|
+
};
|
|
9934
|
+
|
|
9473
9935
|
const DEVICE_URL = {
|
|
9474
9936
|
LOCAL_WEB: 'my-web-url',
|
|
9475
9937
|
LOCAL_MAC: 'my-mac-url',
|
|
@@ -9481,11 +9943,14 @@ describe('plugin-meetings', () => {
|
|
|
9481
9943
|
beneficiaryId = null,
|
|
9482
9944
|
disposition = null,
|
|
9483
9945
|
deviceUrlSharing = null,
|
|
9484
|
-
annotation = undefined
|
|
9946
|
+
annotation = undefined,
|
|
9947
|
+
resourceType = undefined
|
|
9485
9948
|
) => ({
|
|
9486
9949
|
beneficiaryId,
|
|
9487
9950
|
disposition,
|
|
9488
9951
|
deviceUrlSharing,
|
|
9952
|
+
annotation,
|
|
9953
|
+
resourceType,
|
|
9489
9954
|
});
|
|
9490
9955
|
const generateWhiteboard = (
|
|
9491
9956
|
beneficiaryId = null,
|
|
@@ -9504,7 +9969,8 @@ describe('plugin-meetings', () => {
|
|
|
9504
9969
|
annotation,
|
|
9505
9970
|
url,
|
|
9506
9971
|
shareInstanceId,
|
|
9507
|
-
deviceUrlSharing
|
|
9972
|
+
deviceUrlSharing,
|
|
9973
|
+
resourceType
|
|
9508
9974
|
) => {
|
|
9509
9975
|
const newPayload = cloneDeep(payload);
|
|
9510
9976
|
|
|
@@ -9538,7 +10004,8 @@ describe('plugin-meetings', () => {
|
|
|
9538
10004
|
beneficiaryId,
|
|
9539
10005
|
FLOOR_ACTION.GRANTED,
|
|
9540
10006
|
deviceUrlSharing,
|
|
9541
|
-
annotation
|
|
10007
|
+
annotation,
|
|
10008
|
+
resourceType
|
|
9542
10009
|
);
|
|
9543
10010
|
|
|
9544
10011
|
if (isEqual(newPayload.current, newPayload.previous)) {
|
|
@@ -9599,6 +10066,7 @@ describe('plugin-meetings', () => {
|
|
|
9599
10066
|
url,
|
|
9600
10067
|
shareInstanceId,
|
|
9601
10068
|
annotationInfo: undefined,
|
|
10069
|
+
resourceType: undefined,
|
|
9602
10070
|
},
|
|
9603
10071
|
});
|
|
9604
10072
|
}
|
|
@@ -10440,7 +10908,8 @@ describe('plugin-meetings', () => {
|
|
|
10440
10908
|
undefined,
|
|
10441
10909
|
undefined,
|
|
10442
10910
|
undefined,
|
|
10443
|
-
DEVICE_URL.REMOTE_A
|
|
10911
|
+
DEVICE_URL.REMOTE_A,
|
|
10912
|
+
undefined
|
|
10444
10913
|
);
|
|
10445
10914
|
const data2 = generateData(
|
|
10446
10915
|
data1.payload,
|
|
@@ -10453,9 +10922,39 @@ describe('plugin-meetings', () => {
|
|
|
10453
10922
|
undefined,
|
|
10454
10923
|
undefined,
|
|
10455
10924
|
undefined,
|
|
10456
|
-
DEVICE_URL.REMOTE_B
|
|
10925
|
+
DEVICE_URL.REMOTE_B,
|
|
10926
|
+
undefined
|
|
10927
|
+
);
|
|
10928
|
+
const data3 = generateData(data2.payload, false, true, USER_IDS.REMOTE_B, undefined);
|
|
10929
|
+
|
|
10930
|
+
payloadTestHelper([data1, data2, data3]);
|
|
10931
|
+
});
|
|
10932
|
+
});
|
|
10933
|
+
|
|
10934
|
+
describe('File Share --> Desktop Share', () => {
|
|
10935
|
+
it('Scenario #1: remote person A shares file then share desktop', () => {
|
|
10936
|
+
const data1 = generateData(
|
|
10937
|
+
blankPayload,
|
|
10938
|
+
true,
|
|
10939
|
+
true,
|
|
10940
|
+
USER_IDS.ME,
|
|
10941
|
+
undefined,
|
|
10942
|
+
false,
|
|
10943
|
+
undefined,
|
|
10944
|
+
undefined,
|
|
10945
|
+
undefined,
|
|
10946
|
+
undefined,
|
|
10947
|
+
DEVICE_URL.LOCAL_WEB,
|
|
10948
|
+
SHARE_TYPE.FILE
|
|
10949
|
+
);
|
|
10950
|
+
const data2 = generateData(
|
|
10951
|
+
data1.payload,
|
|
10952
|
+
true,
|
|
10953
|
+
false,
|
|
10954
|
+
USER_IDS.ME,
|
|
10955
|
+
SHARE_TYPE.DESKTOP
|
|
10457
10956
|
);
|
|
10458
|
-
const data3 = generateData(data2.payload,
|
|
10957
|
+
const data3 = generateData(data2.payload, true, true, USER_IDS.ME);
|
|
10459
10958
|
|
|
10460
10959
|
payloadTestHelper([data1, data2, data3]);
|
|
10461
10960
|
});
|