@webex/plugin-meetings 3.3.1-next.13 → 3.3.1-next.15
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 +7 -2
- package/dist/breakouts/index.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/meeting/index.js +5 -1
- package/dist/meeting/index.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/reachability/clusterReachability.js +108 -53
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +415 -56
- package/dist/reachability/index.js.map +1 -1
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/reachability/clusterReachability.d.ts +31 -3
- package/dist/types/reachability/index.d.ts +93 -2
- package/dist/webinar/index.js +1 -1
- package/package.json +4 -4
- package/src/breakouts/index.ts +7 -1
- package/src/meeting/index.ts +7 -2
- package/src/metrics/constants.ts +1 -0
- package/src/reachability/clusterReachability.ts +86 -25
- package/src/reachability/index.ts +313 -27
- package/test/unit/spec/breakouts/index.ts +51 -32
- package/test/unit/spec/meeting/index.js +34 -1
- package/test/unit/spec/reachability/clusterReachability.ts +116 -22
- package/test/unit/spec/reachability/index.ts +1120 -84
|
@@ -87,6 +87,7 @@ describe('plugin-meetings', () => {
|
|
|
87
87
|
// @ts-ignore
|
|
88
88
|
webex = new MockWebex({});
|
|
89
89
|
webex.internal.llm.on = sinon.stub();
|
|
90
|
+
webex.internal.llm.isConnected = sinon.stub();
|
|
90
91
|
webex.internal.mercury.on = sinon.stub();
|
|
91
92
|
breakouts = new Breakouts({}, {parent: webex});
|
|
92
93
|
breakouts.groupId = 'groupId';
|
|
@@ -225,38 +226,6 @@ describe('plugin-meetings', () => {
|
|
|
225
226
|
});
|
|
226
227
|
});
|
|
227
228
|
|
|
228
|
-
describe('#listenToBroadcastMessages', () => {
|
|
229
|
-
it('triggers message event when a message received', () => {
|
|
230
|
-
const call = webex.internal.llm.on.getCall(0);
|
|
231
|
-
const callback = call.args[1];
|
|
232
|
-
|
|
233
|
-
assert.equal(call.args[0], 'event:breakout.message');
|
|
234
|
-
|
|
235
|
-
let message;
|
|
236
|
-
|
|
237
|
-
breakouts.listenTo(breakouts, BREAKOUTS.EVENTS.MESSAGE, (event) => {
|
|
238
|
-
message = event;
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
breakouts.currentBreakoutSession.sessionId = 'sessionId';
|
|
242
|
-
|
|
243
|
-
callback({
|
|
244
|
-
data: {
|
|
245
|
-
senderUserId: 'senderUserId',
|
|
246
|
-
sentTime: 'sentTime',
|
|
247
|
-
message: 'message',
|
|
248
|
-
},
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
assert.deepEqual(message, {
|
|
252
|
-
senderUserId: 'senderUserId',
|
|
253
|
-
sentTime: 'sentTime',
|
|
254
|
-
message: 'message',
|
|
255
|
-
sessionId: 'sessionId',
|
|
256
|
-
});
|
|
257
|
-
});
|
|
258
|
-
});
|
|
259
|
-
|
|
260
229
|
describe('#listenToBreakoutRosters', () => {
|
|
261
230
|
it('triggers member update event when a roster received', () => {
|
|
262
231
|
const call = webex.internal.mercury.on.getCall(0);
|
|
@@ -496,8 +465,58 @@ describe('plugin-meetings', () => {
|
|
|
496
465
|
describe('#locusUrlUpdate', () => {
|
|
497
466
|
it('sets the locus url', () => {
|
|
498
467
|
breakouts.locusUrlUpdate('newUrl');
|
|
468
|
+
assert.equal(breakouts.locusUrl, 'newUrl');
|
|
469
|
+
});
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
describe('#listenToBroadcastMessages', () => {
|
|
473
|
+
it('do not subscribe message if llm not connected', () => {
|
|
474
|
+
webex.internal.llm.isConnected = sinon.stub().returns(false);
|
|
475
|
+
breakouts.listenTo = sinon.stub();
|
|
476
|
+
breakouts.locusUrlUpdate('newUrl');
|
|
477
|
+
assert.equal(breakouts.locusUrl, 'newUrl');
|
|
478
|
+
assert.notCalled(breakouts.listenTo);
|
|
479
|
+
});
|
|
499
480
|
|
|
481
|
+
it('do not subscribe message if already done', () => {
|
|
482
|
+
webex.internal.llm.isConnected = sinon.stub().returns(true);
|
|
483
|
+
breakouts.hasSubscribedToMessage = true;
|
|
484
|
+
breakouts.listenTo = sinon.stub();
|
|
485
|
+
breakouts.locusUrlUpdate('newUrl');
|
|
500
486
|
assert.equal(breakouts.locusUrl, 'newUrl');
|
|
487
|
+
assert.notCalled(breakouts.listenTo);
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
it('triggers message event when a message received', () => {
|
|
491
|
+
webex.internal.llm.isConnected = sinon.stub().returns(true);
|
|
492
|
+
breakouts.locusUrlUpdate('newUrl');
|
|
493
|
+
const call = webex.internal.llm.on.getCall(0);
|
|
494
|
+
const callback = call.args[1];
|
|
495
|
+
|
|
496
|
+
assert.equal(call.args[0], 'event:breakout.message');
|
|
497
|
+
|
|
498
|
+
let message;
|
|
499
|
+
|
|
500
|
+
breakouts.listenTo(breakouts, BREAKOUTS.EVENTS.MESSAGE, (event) => {
|
|
501
|
+
message = event;
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
breakouts.currentBreakoutSession.sessionId = 'sessionId';
|
|
505
|
+
|
|
506
|
+
callback({
|
|
507
|
+
data: {
|
|
508
|
+
senderUserId: 'senderUserId',
|
|
509
|
+
sentTime: 'sentTime',
|
|
510
|
+
message: 'message',
|
|
511
|
+
},
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
assert.deepEqual(message, {
|
|
515
|
+
senderUserId: 'senderUserId',
|
|
516
|
+
sentTime: 'sentTime',
|
|
517
|
+
message: 'message',
|
|
518
|
+
sessionId: 'sessionId',
|
|
519
|
+
});
|
|
501
520
|
});
|
|
502
521
|
});
|
|
503
522
|
|
|
@@ -6275,7 +6275,7 @@ describe('plugin-meetings', () => {
|
|
|
6275
6275
|
},
|
|
6276
6276
|
'SELF_OBSERVING'
|
|
6277
6277
|
);
|
|
6278
|
-
|
|
6278
|
+
|
|
6279
6279
|
|
|
6280
6280
|
// Verify that the event handler behaves as expected
|
|
6281
6281
|
expect(meeting.statsAnalyzer.stopAnalyzer.calledOnce).to.be.true;
|
|
@@ -9781,6 +9781,7 @@ describe('plugin-meetings', () => {
|
|
|
9781
9781
|
beforeEach(() => {
|
|
9782
9782
|
webex.internal.llm.isConnected = sinon.stub().returns(false);
|
|
9783
9783
|
webex.internal.llm.getLocusUrl = sinon.stub();
|
|
9784
|
+
webex.internal.llm.getDatachannelUrl = sinon.stub();
|
|
9784
9785
|
webex.internal.llm.registerAndConnect = sinon
|
|
9785
9786
|
.stub()
|
|
9786
9787
|
.returns(Promise.resolve('something'));
|
|
@@ -9808,6 +9809,7 @@ describe('plugin-meetings', () => {
|
|
|
9808
9809
|
meeting.joinedWith = {state: 'JOINED'};
|
|
9809
9810
|
webex.internal.llm.isConnected.returns(true);
|
|
9810
9811
|
webex.internal.llm.getLocusUrl.returns('a url');
|
|
9812
|
+
webex.internal.llm.getDatachannelUrl.returns('a datachannel url');
|
|
9811
9813
|
|
|
9812
9814
|
meeting.locusInfo = {url: 'a url', info: {datachannelUrl: 'a datachannel url'}};
|
|
9813
9815
|
|
|
@@ -9844,6 +9846,7 @@ describe('plugin-meetings', () => {
|
|
|
9844
9846
|
meeting.joinedWith = {state: 'JOINED'};
|
|
9845
9847
|
webex.internal.llm.isConnected.returns(true);
|
|
9846
9848
|
webex.internal.llm.getLocusUrl.returns('a url');
|
|
9849
|
+
webex.internal.llm.getDatachannelUrl.returns('a datachannel url');
|
|
9847
9850
|
|
|
9848
9851
|
meeting.locusInfo = {url: 'a different url', info: {datachannelUrl: 'a datachannel url'}};
|
|
9849
9852
|
|
|
@@ -9869,6 +9872,36 @@ describe('plugin-meetings', () => {
|
|
|
9869
9872
|
);
|
|
9870
9873
|
});
|
|
9871
9874
|
|
|
9875
|
+
it('disconnects if first if the data channel url has changed', async () => {
|
|
9876
|
+
meeting.joinedWith = {state: 'JOINED'};
|
|
9877
|
+
webex.internal.llm.isConnected.returns(true);
|
|
9878
|
+
webex.internal.llm.getLocusUrl.returns('a url');
|
|
9879
|
+
webex.internal.llm.getDatachannelUrl.returns('a datachannel url');
|
|
9880
|
+
|
|
9881
|
+
meeting.locusInfo = {url: 'a url', info: {datachannelUrl: 'a different datachannel url'}};
|
|
9882
|
+
|
|
9883
|
+
const result = await meeting.updateLLMConnection();
|
|
9884
|
+
|
|
9885
|
+
assert.calledWith(webex.internal.llm.disconnectLLM);
|
|
9886
|
+
assert.calledWith(
|
|
9887
|
+
webex.internal.llm.registerAndConnect,
|
|
9888
|
+
'a url',
|
|
9889
|
+
'a different datachannel url'
|
|
9890
|
+
);
|
|
9891
|
+
assert.equal(result, 'something');
|
|
9892
|
+
assert.calledWithExactly(
|
|
9893
|
+
meeting.webex.internal.llm.off,
|
|
9894
|
+
'event:relay.event',
|
|
9895
|
+
meeting.processRelayEvent
|
|
9896
|
+
);
|
|
9897
|
+
assert.calledTwice(meeting.webex.internal.llm.off);
|
|
9898
|
+
assert.calledOnceWithExactly(
|
|
9899
|
+
meeting.webex.internal.llm.on,
|
|
9900
|
+
'event:relay.event',
|
|
9901
|
+
meeting.processRelayEvent
|
|
9902
|
+
);
|
|
9903
|
+
});
|
|
9904
|
+
|
|
9872
9905
|
it('disconnects when the state is not JOINED', async () => {
|
|
9873
9906
|
meeting.joinedWith = {state: 'any other state'};
|
|
9874
9907
|
webex.internal.llm.isConnected.returns(true);
|
|
@@ -4,15 +4,28 @@ import sinon from 'sinon';
|
|
|
4
4
|
import testUtils from '../../../utils/testUtils';
|
|
5
5
|
|
|
6
6
|
// packages/@webex/plugin-meetings/test/unit/spec/reachability/clusterReachability.ts
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
ClusterReachability,
|
|
9
|
+
ResultEventData,
|
|
10
|
+
Events,
|
|
11
|
+
ClientMediaIpsUpdatedEventData,
|
|
12
|
+
} from '@webex/plugin-meetings/src/reachability/clusterReachability'; // replace with actual path
|
|
8
13
|
|
|
9
14
|
describe('ClusterReachability', () => {
|
|
10
15
|
let previousRTCPeerConnection;
|
|
11
16
|
let clusterReachability;
|
|
12
17
|
let fakePeerConnection;
|
|
13
18
|
|
|
19
|
+
const emittedEvents: Record<Events, (ResultEventData | ClientMediaIpsUpdatedEventData)[]> = {
|
|
20
|
+
[Events.resultReady]: [],
|
|
21
|
+
[Events.clientMediaIpsUpdated]: [],
|
|
22
|
+
};
|
|
14
23
|
const FAKE_OFFER = {type: 'offer', sdp: 'fake sdp'};
|
|
15
24
|
|
|
25
|
+
const resetEmittedEvents = () => {
|
|
26
|
+
emittedEvents[Events.resultReady].length = 0;
|
|
27
|
+
emittedEvents[Events.clientMediaIpsUpdated].length = 0;
|
|
28
|
+
};
|
|
16
29
|
beforeEach(() => {
|
|
17
30
|
fakePeerConnection = {
|
|
18
31
|
createOffer: sinon.stub().resolves(FAKE_OFFER),
|
|
@@ -30,6 +43,16 @@ describe('ClusterReachability', () => {
|
|
|
30
43
|
tcp: ['stun:tcp1.webex.com', 'stun:tcp2.webex.com:5004'],
|
|
31
44
|
xtls: ['stun:xtls1.webex.com', 'stun:xtls2.webex.com:443'],
|
|
32
45
|
});
|
|
46
|
+
|
|
47
|
+
resetEmittedEvents();
|
|
48
|
+
|
|
49
|
+
clusterReachability.on(Events.resultReady, (data: ResultEventData) => {
|
|
50
|
+
emittedEvents[Events.resultReady].push(data);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
clusterReachability.on(Events.clientMediaIpsUpdated, (data: ClientMediaIpsUpdatedEventData) => {
|
|
54
|
+
emittedEvents[Events.clientMediaIpsUpdated].push(data);
|
|
55
|
+
});
|
|
33
56
|
});
|
|
34
57
|
|
|
35
58
|
afterEach(() => {
|
|
@@ -98,6 +121,10 @@ describe('ClusterReachability', () => {
|
|
|
98
121
|
tcp: {result: 'untested'},
|
|
99
122
|
xtls: {result: 'untested'},
|
|
100
123
|
});
|
|
124
|
+
|
|
125
|
+
// verify that no events were emitted
|
|
126
|
+
assert.deepEqual(emittedEvents[Events.resultReady], []);
|
|
127
|
+
assert.deepEqual(emittedEvents[Events.clientMediaIpsUpdated], []);
|
|
101
128
|
});
|
|
102
129
|
|
|
103
130
|
describe('#start', () => {
|
|
@@ -124,8 +151,12 @@ describe('ClusterReachability', () => {
|
|
|
124
151
|
assert.calledOnceWithExactly(fakePeerConnection.createOffer, {offerToReceiveAudio: true});
|
|
125
152
|
assert.calledOnce(fakePeerConnection.setLocalDescription);
|
|
126
153
|
|
|
127
|
-
|
|
154
|
+
clusterReachability.abort();
|
|
128
155
|
await promise;
|
|
156
|
+
|
|
157
|
+
// verify that no events were emitted
|
|
158
|
+
assert.deepEqual(emittedEvents[Events.resultReady], []);
|
|
159
|
+
assert.deepEqual(emittedEvents[Events.clientMediaIpsUpdated], []);
|
|
129
160
|
});
|
|
130
161
|
|
|
131
162
|
it('resolves and has correct result as soon as it finds that all udp, tcp and tls are reachable', async () => {
|
|
@@ -134,14 +165,44 @@ describe('ClusterReachability', () => {
|
|
|
134
165
|
await clock.tickAsync(100);
|
|
135
166
|
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp'}});
|
|
136
167
|
|
|
168
|
+
// check the right events were emitted
|
|
169
|
+
assert.equal(emittedEvents[Events.resultReady].length, 1);
|
|
170
|
+
assert.deepEqual(emittedEvents[Events.resultReady][0], {
|
|
171
|
+
protocol: 'udp',
|
|
172
|
+
result: 'reachable',
|
|
173
|
+
latencyInMilliseconds: 100,
|
|
174
|
+
clientMediaIPs: ['somePublicIp'],
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// clientMediaIpsUpdated shouldn't be emitted, because the IP is already passed in the resultReady event
|
|
178
|
+
assert.equal(emittedEvents[Events.clientMediaIpsUpdated].length, 0);
|
|
179
|
+
|
|
137
180
|
await clock.tickAsync(100);
|
|
138
181
|
fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp'}});
|
|
139
182
|
|
|
183
|
+
// check the right event was emitted
|
|
184
|
+
assert.equal(emittedEvents[Events.resultReady].length, 2);
|
|
185
|
+
assert.deepEqual(emittedEvents[Events.resultReady][1], {
|
|
186
|
+
protocol: 'tcp',
|
|
187
|
+
result: 'reachable',
|
|
188
|
+
latencyInMilliseconds: 200,
|
|
189
|
+
});
|
|
190
|
+
assert.equal(emittedEvents[Events.clientMediaIpsUpdated].length, 0);
|
|
191
|
+
|
|
140
192
|
await clock.tickAsync(100);
|
|
141
193
|
fakePeerConnection.onicecandidate({
|
|
142
194
|
candidate: {type: 'relay', address: 'someTurnRelayIp', port: 443},
|
|
143
195
|
});
|
|
144
196
|
|
|
197
|
+
// check the right event was emitted
|
|
198
|
+
assert.equal(emittedEvents[Events.resultReady].length, 3);
|
|
199
|
+
assert.deepEqual(emittedEvents[Events.resultReady][2], {
|
|
200
|
+
protocol: 'xtls',
|
|
201
|
+
result: 'reachable',
|
|
202
|
+
latencyInMilliseconds: 300,
|
|
203
|
+
});
|
|
204
|
+
assert.equal(emittedEvents[Events.clientMediaIpsUpdated].length, 0);
|
|
205
|
+
|
|
145
206
|
await promise;
|
|
146
207
|
|
|
147
208
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
@@ -151,13 +212,17 @@ describe('ClusterReachability', () => {
|
|
|
151
212
|
});
|
|
152
213
|
});
|
|
153
214
|
|
|
154
|
-
it('
|
|
215
|
+
it('resolves and returns correct results when aborted before it gets any candidates', async () => {
|
|
155
216
|
const promise = clusterReachability.start();
|
|
156
217
|
|
|
157
218
|
// progress time without any candidates
|
|
158
|
-
|
|
219
|
+
clusterReachability.abort();
|
|
159
220
|
await promise;
|
|
160
221
|
|
|
222
|
+
// verify that no events were emitted
|
|
223
|
+
assert.deepEqual(emittedEvents[Events.resultReady], []);
|
|
224
|
+
assert.deepEqual(emittedEvents[Events.clientMediaIpsUpdated], []);
|
|
225
|
+
|
|
161
226
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
162
227
|
udp: {result: 'unreachable'},
|
|
163
228
|
tcp: {result: 'unreachable'},
|
|
@@ -165,22 +230,26 @@ describe('ClusterReachability', () => {
|
|
|
165
230
|
});
|
|
166
231
|
});
|
|
167
232
|
|
|
168
|
-
it('
|
|
169
|
-
clusterReachability = new ClusterReachability('testName', {
|
|
170
|
-
isVideoMesh: true,
|
|
171
|
-
udp: ['stun:udp1', 'stun:udp2'],
|
|
172
|
-
tcp: ['stun:tcp1.webex.com', 'stun:tcp2.webex.com:5004'],
|
|
173
|
-
xtls: ['stun:xtls1.webex.com', 'stun:xtls1.webex.com:443'],
|
|
174
|
-
});
|
|
175
|
-
|
|
233
|
+
it('resolves and returns correct results when aborted after getting some candidates', async () => {
|
|
176
234
|
const promise = clusterReachability.start();
|
|
177
235
|
|
|
178
|
-
|
|
179
|
-
|
|
236
|
+
await clock.tickAsync(100);
|
|
237
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp'}});
|
|
238
|
+
|
|
239
|
+
// check the right event was emitted
|
|
240
|
+
assert.equal(emittedEvents[Events.resultReady].length, 1);
|
|
241
|
+
assert.deepEqual(emittedEvents[Events.resultReady][0], {
|
|
242
|
+
protocol: 'udp',
|
|
243
|
+
result: 'reachable',
|
|
244
|
+
latencyInMilliseconds: 100,
|
|
245
|
+
clientMediaIPs: ['somePublicIp'],
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
clusterReachability.abort();
|
|
180
249
|
await promise;
|
|
181
250
|
|
|
182
251
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
183
|
-
udp: {result: '
|
|
252
|
+
udp: {result: 'reachable', latencyInMilliseconds: 100, clientMediaIPs: ['somePublicIp']},
|
|
184
253
|
tcp: {result: 'unreachable'},
|
|
185
254
|
xtls: {result: 'unreachable'},
|
|
186
255
|
});
|
|
@@ -233,8 +302,7 @@ describe('ClusterReachability', () => {
|
|
|
233
302
|
await clock.tickAsync(10);
|
|
234
303
|
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp3'}});
|
|
235
304
|
|
|
236
|
-
|
|
237
|
-
|
|
305
|
+
clusterReachability.abort();
|
|
238
306
|
await promise;
|
|
239
307
|
|
|
240
308
|
// latency should be from only the first candidates, but the clientMediaIps should be from all UDP candidates (not TCP)
|
|
@@ -262,8 +330,7 @@ describe('ClusterReachability', () => {
|
|
|
262
330
|
await clock.tickAsync(10);
|
|
263
331
|
fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp3'}});
|
|
264
332
|
|
|
265
|
-
|
|
266
|
-
|
|
333
|
+
clusterReachability.abort();
|
|
267
334
|
await promise;
|
|
268
335
|
|
|
269
336
|
// latency should be from only the first candidates, but the clientMediaIps should be from only from UDP candidates
|
|
@@ -293,8 +360,7 @@ describe('ClusterReachability', () => {
|
|
|
293
360
|
candidate: {type: 'relay', address: 'someTurnRelayIp3', port: 443},
|
|
294
361
|
});
|
|
295
362
|
|
|
296
|
-
|
|
297
|
-
|
|
363
|
+
clusterReachability.abort();
|
|
298
364
|
await promise;
|
|
299
365
|
|
|
300
366
|
// latency should be from only the first candidates, but the clientMediaIps should be from only from UDP candidates
|
|
@@ -305,22 +371,50 @@ describe('ClusterReachability', () => {
|
|
|
305
371
|
});
|
|
306
372
|
});
|
|
307
373
|
|
|
308
|
-
it('ignores duplicate
|
|
374
|
+
it('handles new found public IPs and ignores duplicate IPs', async () => {
|
|
309
375
|
const promise = clusterReachability.start();
|
|
310
376
|
|
|
311
377
|
// generate candidates with duplicate addresses
|
|
312
378
|
await clock.tickAsync(10);
|
|
313
379
|
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1'}});
|
|
314
380
|
|
|
381
|
+
// check events emitted: there should be a resultReady and no clientMediaIpsUpdated
|
|
382
|
+
assert.equal(emittedEvents[Events.resultReady].length, 1);
|
|
383
|
+
assert.deepEqual(emittedEvents[Events.resultReady][0], {
|
|
384
|
+
protocol: 'udp',
|
|
385
|
+
result: 'reachable',
|
|
386
|
+
latencyInMilliseconds: 10,
|
|
387
|
+
clientMediaIPs: ['somePublicIp1'],
|
|
388
|
+
});
|
|
389
|
+
assert.equal(emittedEvents[Events.clientMediaIpsUpdated].length, 0);
|
|
390
|
+
resetEmittedEvents();
|
|
391
|
+
|
|
315
392
|
await clock.tickAsync(10);
|
|
316
393
|
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1'}});
|
|
317
394
|
|
|
395
|
+
// no new event was emitted
|
|
396
|
+
assert.equal(emittedEvents[Events.resultReady].length, 0);
|
|
397
|
+
assert.equal(emittedEvents[Events.clientMediaIpsUpdated].length, 0);
|
|
398
|
+
|
|
318
399
|
await clock.tickAsync(10);
|
|
319
400
|
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp2'}});
|
|
320
401
|
|
|
402
|
+
// check new events: now only clientMediaIpsUpdated event and no resultReady events
|
|
403
|
+
assert.equal(emittedEvents[Events.resultReady].length, 0);
|
|
404
|
+
assert.equal(emittedEvents[Events.clientMediaIpsUpdated].length, 1);
|
|
405
|
+
assert.deepEqual(emittedEvents[Events.clientMediaIpsUpdated][0], {
|
|
406
|
+
protocol: 'udp',
|
|
407
|
+
clientMediaIPs: ['somePublicIp1', 'somePublicIp2'],
|
|
408
|
+
});
|
|
409
|
+
resetEmittedEvents();
|
|
410
|
+
|
|
321
411
|
await clock.tickAsync(10);
|
|
322
412
|
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp2'}});
|
|
323
413
|
|
|
414
|
+
// no new event was emitted
|
|
415
|
+
assert.equal(emittedEvents[Events.resultReady].length, 0);
|
|
416
|
+
assert.equal(emittedEvents[Events.clientMediaIpsUpdated].length, 0);
|
|
417
|
+
|
|
324
418
|
// send also a relay candidate so that the reachability check finishes
|
|
325
419
|
fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp'}});
|
|
326
420
|
fakePeerConnection.onicecandidate({
|