@webex/plugin-meetings 3.0.0-beta.47 → 3.0.0-beta.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/constants.js +0 -1
- package/dist/constants.js.map +1 -1
- package/dist/locus-info/index.js +1 -1
- package/dist/locus-info/index.js.map +1 -1
- package/dist/media/index.js +5 -2
- package/dist/media/index.js.map +1 -1
- package/dist/meeting/index.js +5 -3
- package/dist/meeting/index.js.map +1 -1
- package/dist/reachability/index.js +47 -10
- package/dist/reachability/index.js.map +1 -1
- package/dist/types/constants.d.ts +0 -1
- package/dist/types/reachability/index.d.ts +15 -3
- package/package.json +19 -19
- package/src/constants.ts +0 -1
- package/src/locus-info/index.ts +1 -1
- package/src/media/index.ts +9 -2
- package/src/meeting/index.ts +7 -5
- package/src/reachability/index.ts +50 -11
- package/test/unit/spec/locus-info/index.js +3 -3
- package/test/unit/spec/media/index.ts +63 -1
- package/test/unit/spec/meeting/index.js +38 -1
- package/test/unit/spec/reachability/index.ts +114 -8
|
@@ -3,6 +3,7 @@ import Media from '@webex/plugin-meetings/src/media/index';
|
|
|
3
3
|
import {assert} from '@webex/test-helper-chai';
|
|
4
4
|
import sinon from 'sinon';
|
|
5
5
|
import StaticConfig from '@webex/plugin-meetings/src/common/config';
|
|
6
|
+
import { forEach } from 'lodash';
|
|
6
7
|
|
|
7
8
|
describe('createMediaConnection', () => {
|
|
8
9
|
const fakeRoapMediaConnection = {
|
|
@@ -103,6 +104,16 @@ describe('createMediaConnection', () => {
|
|
|
103
104
|
.returns(fakeRoapMediaConnection);
|
|
104
105
|
|
|
105
106
|
Media.createMediaConnection(true, 'some debug id', {
|
|
107
|
+
mediaProperties: {
|
|
108
|
+
mediaDirection: {
|
|
109
|
+
sendAudio: true,
|
|
110
|
+
sendVideo: true,
|
|
111
|
+
sendShare: false,
|
|
112
|
+
receiveAudio: true,
|
|
113
|
+
receiveVideo: true,
|
|
114
|
+
receiveShare: true,
|
|
115
|
+
}
|
|
116
|
+
},
|
|
106
117
|
turnServerInfo: {
|
|
107
118
|
url: 'turn server url',
|
|
108
119
|
username: 'turn username',
|
|
@@ -120,22 +131,73 @@ describe('createMediaConnection', () => {
|
|
|
120
131
|
credential: 'turn password',
|
|
121
132
|
},
|
|
122
133
|
],
|
|
134
|
+
enableMainAudio: true,
|
|
135
|
+
enableMainVideo: true,
|
|
123
136
|
},
|
|
124
137
|
'some debug id'
|
|
125
138
|
);
|
|
126
139
|
});
|
|
127
140
|
|
|
141
|
+
forEach([
|
|
142
|
+
{sendAudio: true, receiveAudio: true, sendVideo: true, receiveVideo: true, enableMainAudio: true, enableMainVideo: true,},
|
|
143
|
+
{sendAudio: true, receiveAudio: false, sendVideo: true, receiveVideo: false, enableMainAudio: true, enableMainVideo: true,},
|
|
144
|
+
{sendAudio: false, receiveAudio: true, sendVideo: false, receiveVideo: true, enableMainAudio: true, enableMainVideo: true,},
|
|
145
|
+
{sendAudio: false, receiveAudio: false, sendVideo: false, receiveVideo: false, enableMainAudio: false, enableMainVideo: false,},
|
|
146
|
+
], ({sendAudio, sendVideo, receiveAudio, receiveVideo, enableMainAudio, enableMainVideo}) => {
|
|
147
|
+
it(`sets enableMainVideo to ${enableMainVideo} and enableMainAudio to ${enableMainAudio} when sendAudio: ${sendAudio} sendVideo: ${sendVideo} receiveAudio: ${receiveAudio} receiveVideo: ${receiveVideo}`, () => {
|
|
148
|
+
const multistreamRoapMediaConnectionConstructorStub = sinon
|
|
149
|
+
.stub(internalMediaModule, 'MultistreamRoapMediaConnection')
|
|
150
|
+
.returns(fakeRoapMediaConnection);
|
|
151
|
+
|
|
152
|
+
Media.createMediaConnection(true, 'some debug id', {
|
|
153
|
+
mediaProperties: {
|
|
154
|
+
mediaDirection: {
|
|
155
|
+
sendAudio,
|
|
156
|
+
sendVideo,
|
|
157
|
+
sendShare: false,
|
|
158
|
+
receiveAudio,
|
|
159
|
+
receiveVideo,
|
|
160
|
+
receiveShare: true,
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
assert.calledOnce(multistreamRoapMediaConnectionConstructorStub);
|
|
165
|
+
assert.calledWith(
|
|
166
|
+
multistreamRoapMediaConnectionConstructorStub,
|
|
167
|
+
{
|
|
168
|
+
iceServers: [],
|
|
169
|
+
enableMainAudio,
|
|
170
|
+
enableMainVideo,
|
|
171
|
+
},
|
|
172
|
+
'some debug id'
|
|
173
|
+
);
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
128
177
|
it('passes empty ICE servers array to MultistreamRoapMediaConnection if turnServerInfo is undefined (multistream enabled)', () => {
|
|
129
178
|
const multistreamRoapMediaConnectionConstructorStub = sinon
|
|
130
179
|
.stub(internalMediaModule, 'MultistreamRoapMediaConnection')
|
|
131
180
|
.returns(fakeRoapMediaConnection);
|
|
132
181
|
|
|
133
|
-
Media.createMediaConnection(true, 'debug string', {
|
|
182
|
+
Media.createMediaConnection(true, 'debug string', {
|
|
183
|
+
mediaProperties: {
|
|
184
|
+
mediaDirection: {
|
|
185
|
+
sendAudio: true,
|
|
186
|
+
sendVideo: true,
|
|
187
|
+
sendShare: false,
|
|
188
|
+
receiveAudio: true,
|
|
189
|
+
receiveVideo: true,
|
|
190
|
+
receiveShare: true,
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
});
|
|
134
194
|
assert.calledOnce(multistreamRoapMediaConnectionConstructorStub);
|
|
135
195
|
assert.calledWith(
|
|
136
196
|
multistreamRoapMediaConnectionConstructorStub,
|
|
137
197
|
{
|
|
138
198
|
iceServers: [],
|
|
199
|
+
enableMainAudio: true,
|
|
200
|
+
enableMainVideo: true,
|
|
139
201
|
},
|
|
140
202
|
'debug string'
|
|
141
203
|
);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
3
|
*/
|
|
4
4
|
import 'jsdom-global/register';
|
|
5
|
-
import {cloneDeep, isEqual} from 'lodash';
|
|
5
|
+
import {cloneDeep, forEach, isEqual} from 'lodash';
|
|
6
6
|
import sinon from 'sinon';
|
|
7
7
|
import StateMachine from 'javascript-state-machine';
|
|
8
8
|
import uuid from 'uuid';
|
|
@@ -2195,6 +2195,43 @@ describe('plugin-meetings', () => {
|
|
|
2195
2195
|
sandbox = null;
|
|
2196
2196
|
});
|
|
2197
2197
|
|
|
2198
|
+
forEach(
|
|
2199
|
+
[
|
|
2200
|
+
{receiveAudio: true, sendAudio: true, enableMultistreamAudio: true},
|
|
2201
|
+
{receiveAudio: true, sendAudio: false, enableMultistreamAudio: true},
|
|
2202
|
+
{receiveAudio: false, sendAudio: true, enableMultistreamAudio: true},
|
|
2203
|
+
{receiveAudio: false, sendAudio: false, enableMultistreamAudio: false},
|
|
2204
|
+
],
|
|
2205
|
+
({receiveAudio, sendAudio, enableMultistreamAudio}) => {
|
|
2206
|
+
it(`should call enableMultistreamAudio with ${enableMultistreamAudio} if it is a multistream connection and receiveAudio: ${receiveAudio} sendAudio: ${sendAudio}`, async () => {
|
|
2207
|
+
const mediaSettings = {
|
|
2208
|
+
sendAudio,
|
|
2209
|
+
receiveAudio,
|
|
2210
|
+
sendVideo: true,
|
|
2211
|
+
receiveVideo: true,
|
|
2212
|
+
sendShare: true,
|
|
2213
|
+
receiveShare: true,
|
|
2214
|
+
isSharing: true,
|
|
2215
|
+
};
|
|
2216
|
+
|
|
2217
|
+
meeting.mediaProperties.webrtcMediaConnection = {
|
|
2218
|
+
enableMultistreamAudio: sinon.stub().resolves('some value'),
|
|
2219
|
+
};
|
|
2220
|
+
meeting.isMultistream = true;
|
|
2221
|
+
|
|
2222
|
+
const result = await meeting.updateMedia({
|
|
2223
|
+
mediaSettings,
|
|
2224
|
+
});
|
|
2225
|
+
|
|
2226
|
+
assert.calledOnceWithExactly(
|
|
2227
|
+
meeting.mediaProperties.webrtcMediaConnection.enableMultistreamAudio,
|
|
2228
|
+
enableMultistreamAudio
|
|
2229
|
+
);
|
|
2230
|
+
assert.equal(result, 'some value');
|
|
2231
|
+
});
|
|
2232
|
+
}
|
|
2233
|
+
);
|
|
2234
|
+
|
|
2198
2235
|
it('should use a queue if currently busy', async () => {
|
|
2199
2236
|
const mediaSettings = {
|
|
2200
2237
|
sendAudio: true,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {assert} from '@webex/test-helper-chai';
|
|
2
2
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
3
3
|
import sinon from 'sinon';
|
|
4
|
-
import Reachability from '@webex/plugin-meetings/src/reachability/';
|
|
4
|
+
import Reachability, {ICECandidateResult} from '@webex/plugin-meetings/src/reachability/';
|
|
5
5
|
|
|
6
6
|
describe('isAnyClusterReachable', () => {
|
|
7
7
|
let webex;
|
|
@@ -22,8 +22,8 @@ describe('isAnyClusterReachable', () => {
|
|
|
22
22
|
|
|
23
23
|
const result = await reachability.isAnyClusterReachable();
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
assert.equal(result, expectedValue);
|
|
26
|
+
};
|
|
27
27
|
|
|
28
28
|
it('returns true when udp is reachable', async () => {
|
|
29
29
|
await checkIsClusterReachable({x: {udp: {reachable: 'true'}, tcp: {reachable: 'false'}}}, true);
|
|
@@ -72,24 +72,130 @@ describe('gatherReachability', () => {
|
|
|
72
72
|
udp: 'testUDP',
|
|
73
73
|
},
|
|
74
74
|
},
|
|
75
|
-
}
|
|
75
|
+
};
|
|
76
76
|
const getClustersResult = {
|
|
77
77
|
clusters: {clusterId: 'cluster'},
|
|
78
|
-
joinCookie: {id: 'id'}
|
|
78
|
+
joinCookie: {id: 'id'},
|
|
79
79
|
};
|
|
80
80
|
|
|
81
81
|
reachability.reachabilityRequest.getClusters = sinon.stub().returns(getClustersResult);
|
|
82
|
-
(reachability as any).performReachabilityCheck = sinon.stub().returns(reachabilityResults)
|
|
82
|
+
(reachability as any).performReachabilityCheck = sinon.stub().returns(reachabilityResults);
|
|
83
83
|
|
|
84
84
|
const result = await reachability.gatherReachability();
|
|
85
85
|
|
|
86
86
|
assert.equal(result, reachabilityResults);
|
|
87
87
|
|
|
88
|
-
const storedResultForReachabilityResult = await webex.boundedStorage.get(
|
|
89
|
-
|
|
88
|
+
const storedResultForReachabilityResult = await webex.boundedStorage.get(
|
|
89
|
+
'Reachability',
|
|
90
|
+
'reachability.result'
|
|
91
|
+
);
|
|
92
|
+
const storedResultForJoinCookie = await webex.boundedStorage.get(
|
|
93
|
+
'Reachability',
|
|
94
|
+
'reachability.joinCookie'
|
|
95
|
+
);
|
|
90
96
|
|
|
91
97
|
assert.equal(JSON.stringify(result), storedResultForReachabilityResult);
|
|
92
98
|
assert.equal(JSON.stringify(getClustersResult.joinCookie), storedResultForJoinCookie);
|
|
93
99
|
});
|
|
94
100
|
|
|
101
|
+
describe('clientMediaIPs', () => {
|
|
102
|
+
let testingClass: TestReachability;
|
|
103
|
+
|
|
104
|
+
class TestReachability extends Reachability {
|
|
105
|
+
public testParseIceResultsToReachabilityResults(iceResults: Array<ICECandidateResult>) {
|
|
106
|
+
return this.parseIceResultsToReachabilityResults(iceResults);
|
|
107
|
+
}
|
|
108
|
+
public testAddPublicIP(peerConnection: RTCPeerConnection, publicIP?: string | null) {
|
|
109
|
+
return this.addPublicIP(peerConnection, publicIP);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
beforeEach(() => {
|
|
113
|
+
testingClass = new TestReachability({webex});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('calls parseIceResultsToReachabilityResults correctly', () => {
|
|
117
|
+
const res = testingClass.testParseIceResultsToReachabilityResults([
|
|
118
|
+
{
|
|
119
|
+
clusterId: 'id1',
|
|
120
|
+
elapsed: '12312',
|
|
121
|
+
publicIPs: ['1.1.1.1'],
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
clusterId: 'id2',
|
|
125
|
+
elapsed: null,
|
|
126
|
+
publicIPs: ['1.1.1.1'],
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
clusterId: 'id2',
|
|
130
|
+
elapsed: '14123',
|
|
131
|
+
publicIPs: undefined,
|
|
132
|
+
},
|
|
133
|
+
]);
|
|
134
|
+
|
|
135
|
+
assert.deepEqual(res, {
|
|
136
|
+
id1: {
|
|
137
|
+
tcp: {
|
|
138
|
+
clientMediaIPs: ['1.1.1.1'],
|
|
139
|
+
latencyInMilliseconds: '12312',
|
|
140
|
+
reachable: 'true',
|
|
141
|
+
},
|
|
142
|
+
udp: {
|
|
143
|
+
clientMediaIPs: ['1.1.1.1'],
|
|
144
|
+
latencyInMilliseconds: '12312',
|
|
145
|
+
reachable: 'true',
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
id2: {
|
|
149
|
+
tcp: {
|
|
150
|
+
latencyInMilliseconds: '14123',
|
|
151
|
+
reachable: 'true',
|
|
152
|
+
},
|
|
153
|
+
udp: {
|
|
154
|
+
latencyInMilliseconds: '14123',
|
|
155
|
+
reachable: 'true',
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('calls addPublicIP correctly with no existing public APIs', () => {
|
|
162
|
+
const peerConnection = {
|
|
163
|
+
connectionState: 'not_closed',
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
testingClass.testAddPublicIP(peerConnection as RTCPeerConnection, '1.1.1.1');
|
|
167
|
+
|
|
168
|
+
assert.deepEqual(peerConnection, {
|
|
169
|
+
connectionState: 'not_closed',
|
|
170
|
+
publicIPs: ['1.1.1.1'],
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('calls addPublicIP correctly with existing public APIs', () => {
|
|
175
|
+
const peerConnection = {
|
|
176
|
+
connectionState: 'not_closed',
|
|
177
|
+
publicIPs: ['2.2.2.2'],
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
testingClass.testAddPublicIP(peerConnection as any, '1.1.1.1');
|
|
181
|
+
|
|
182
|
+
assert.deepEqual(peerConnection, {
|
|
183
|
+
connectionState: 'not_closed',
|
|
184
|
+
publicIPs: ['2.2.2.2', '1.1.1.1'],
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('calls addPublicIP correctly null publicAPI', () => {
|
|
189
|
+
const peerConnection = {
|
|
190
|
+
connectionState: 'not_closed',
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
testingClass.testAddPublicIP(peerConnection as RTCPeerConnection, null);
|
|
194
|
+
|
|
195
|
+
assert.deepEqual(peerConnection, {
|
|
196
|
+
connectionState: 'not_closed',
|
|
197
|
+
publicIPs: null,
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
});
|
|
95
201
|
});
|