@webex/plugin-meetings 3.3.1 → 3.4.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 +7 -2
- package/dist/breakouts/index.js.map +1 -1
- package/dist/constants.js +11 -4
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/selfUtils.js +0 -5
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +70 -15
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/index.js +12 -0
- package/dist/media/index.js.map +1 -1
- package/dist/meeting/connectionStateHandler.js +67 -0
- package/dist/meeting/connectionStateHandler.js.map +1 -0
- package/dist/meeting/index.js +552 -357
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +7 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/muteState.js +6 -1
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/util.js +1 -0
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +4 -4
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +2 -2
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/util.js +17 -17
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +16 -16
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +1 -1
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +37 -33
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +8 -0
- package/dist/meetings/meetings.types.js.map +1 -1
- package/dist/meetings/util.js +3 -2
- package/dist/meetings/util.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +57 -0
- package/dist/metrics/index.js.map +1 -1
- package/dist/personal-meeting-room/index.js +1 -1
- package/dist/personal-meeting-room/index.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/constants.d.ts +11 -3
- package/dist/types/media/MediaConnectionAwaiter.d.ts +24 -4
- package/dist/types/meeting/connectionStateHandler.d.ts +30 -0
- package/dist/types/meeting/index.d.ts +27 -7
- package/dist/types/meeting/locusMediaRequest.d.ts +2 -0
- package/dist/types/meeting-info/index.d.ts +3 -2
- package/dist/types/meeting-info/meeting-info-v2.d.ts +3 -2
- package/dist/types/meeting-info/util.d.ts +5 -4
- package/dist/types/meeting-info/utilv2.d.ts +3 -2
- package/dist/types/meetings/collection.d.ts +3 -2
- package/dist/types/meetings/index.d.ts +4 -3
- package/dist/types/meetings/meetings.types.d.ts +9 -0
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/metrics/index.d.ts +15 -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 +23 -23
- package/src/breakouts/index.ts +7 -1
- package/src/constants.ts +13 -17
- package/src/locus-info/selfUtils.ts +0 -5
- package/src/media/MediaConnectionAwaiter.ts +89 -14
- package/src/media/index.ts +13 -0
- package/src/meeting/connectionStateHandler.ts +65 -0
- package/src/meeting/index.ts +526 -292
- package/src/meeting/locusMediaRequest.ts +5 -0
- package/src/meeting/muteState.ts +6 -1
- package/src/meeting/util.ts +1 -0
- package/src/meeting-info/index.ts +9 -6
- package/src/meeting-info/meeting-info-v2.ts +4 -4
- package/src/meeting-info/util.ts +23 -28
- package/src/meeting-info/utilv2.ts +18 -24
- package/src/meetings/collection.ts +3 -3
- package/src/meetings/index.ts +39 -40
- package/src/meetings/meetings.types.ts +11 -0
- package/src/meetings/util.ts +5 -4
- package/src/metrics/constants.ts +1 -0
- package/src/metrics/index.ts +44 -0
- package/src/personal-meeting-room/index.ts +2 -2
- package/src/reachability/clusterReachability.ts +86 -25
- package/src/reachability/index.ts +316 -27
- package/test/unit/spec/breakouts/index.ts +51 -32
- package/test/unit/spec/locus-info/selfUtils.js +25 -23
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +131 -32
- package/test/unit/spec/media/index.ts +42 -27
- package/test/unit/spec/meeting/connectionStateHandler.ts +102 -0
- package/test/unit/spec/meeting/index.js +758 -179
- package/test/unit/spec/meeting/locusMediaRequest.ts +7 -0
- package/test/unit/spec/meeting/muteState.js +24 -0
- package/test/unit/spec/meeting-info/index.js +4 -4
- package/test/unit/spec/meeting-info/meetinginfov2.js +24 -28
- package/test/unit/spec/meeting-info/request.js +2 -2
- package/test/unit/spec/meeting-info/utilv2.js +41 -49
- package/test/unit/spec/meetings/index.js +14 -0
- package/test/unit/spec/metrics/index.js +126 -0
- package/test/unit/spec/multistream/mediaRequestManager.ts +2 -2
- package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -2
- package/test/unit/spec/reachability/clusterReachability.ts +116 -22
- package/test/unit/spec/reachability/index.ts +1153 -84
- package/test/unit/spec/rtcMetrics/index.ts +1 -0
- package/dist/mediaQualityMetrics/config.js +0 -321
- package/dist/mediaQualityMetrics/config.js.map +0 -1
- package/dist/statsAnalyzer/global.js +0 -44
- package/dist/statsAnalyzer/global.js.map +0 -1
- package/dist/statsAnalyzer/index.js +0 -1072
- package/dist/statsAnalyzer/index.js.map +0 -1
- package/dist/statsAnalyzer/mqaUtil.js +0 -368
- package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
- package/dist/types/mediaQualityMetrics/config.d.ts +0 -247
- 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/src/mediaQualityMetrics/config.ts +0 -255
- package/src/statsAnalyzer/global.ts +0 -37
- package/src/statsAnalyzer/index.ts +0 -1318
- package/src/statsAnalyzer/mqaUtil.ts +0 -463
- package/test/unit/spec/stats-analyzer/index.js +0 -1819
|
@@ -58,4 +58,130 @@ describe('Meeting metrics', () => {
|
|
|
58
58
|
});
|
|
59
59
|
});
|
|
60
60
|
});
|
|
61
|
+
|
|
62
|
+
describe('prepareMetricFields', () => {
|
|
63
|
+
it('handles empty objects correctly', () => {
|
|
64
|
+
const result = metrics.prepareMetricFields({});
|
|
65
|
+
|
|
66
|
+
assert.deepEqual(result, {});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('handles literal values correctly', () => {
|
|
70
|
+
assert.deepEqual(metrics.prepareMetricFields('any string'), {value: 'any string'});
|
|
71
|
+
assert.deepEqual(metrics.prepareMetricFields(999), {value: 999});
|
|
72
|
+
assert.deepEqual(metrics.prepareMetricFields(null), {value: null});
|
|
73
|
+
assert.deepEqual(metrics.prepareMetricFields(true), {value: true});
|
|
74
|
+
assert.deepEqual(metrics.prepareMetricFields(false), {value: false});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('handles simple objects correctly', () => {
|
|
78
|
+
const result = metrics.prepareMetricFields({
|
|
79
|
+
someStringProp: 'some string',
|
|
80
|
+
numberProp: 100,
|
|
81
|
+
booleanPropFalse: false,
|
|
82
|
+
booleanPropTrue: true,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
assert.deepEqual(result, {
|
|
86
|
+
someStringProp: 'some string',
|
|
87
|
+
numberProp: 100,
|
|
88
|
+
booleanPropFalse: false,
|
|
89
|
+
booleanPropTrue: true,
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('handles nested objects correctly', () => {
|
|
94
|
+
const result = metrics.prepareMetricFields({
|
|
95
|
+
someStringProp: 'some string',
|
|
96
|
+
nestedObject: {
|
|
97
|
+
stringProp: 'another string',
|
|
98
|
+
numberProp: 1234,
|
|
99
|
+
deepObject: {
|
|
100
|
+
oneMoreString: 'deep nested string',
|
|
101
|
+
someBoolean: true,
|
|
102
|
+
oneMoreNumber: 10,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
assert.deepEqual(result, {
|
|
108
|
+
someStringProp: 'some string',
|
|
109
|
+
nestedObject_stringProp: 'another string',
|
|
110
|
+
nestedObject_numberProp: 1234,
|
|
111
|
+
nestedObject_deepObject_oneMoreString: 'deep nested string',
|
|
112
|
+
nestedObject_deepObject_someBoolean: true,
|
|
113
|
+
nestedObject_deepObject_oneMoreNumber: 10,
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('handles arrays correctly', () => {
|
|
118
|
+
const result = metrics.prepareMetricFields(['a string', 10, true, false, {id: 'object id'}]);
|
|
119
|
+
|
|
120
|
+
assert.deepEqual(result, {
|
|
121
|
+
0: 'a string',
|
|
122
|
+
1: 10,
|
|
123
|
+
2: true,
|
|
124
|
+
3: false,
|
|
125
|
+
'4_id': 'object id',
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('handles arrays nested in objects correctly', () => {
|
|
130
|
+
const result = metrics.prepareMetricFields({
|
|
131
|
+
something: 10,
|
|
132
|
+
anObject: {
|
|
133
|
+
someArray: ['a string', 10, true, false, {id: 'object id'}],
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
assert.deepEqual(result, {
|
|
138
|
+
something: 10,
|
|
139
|
+
anObject_someArray_0: 'a string',
|
|
140
|
+
anObject_someArray_1: 10,
|
|
141
|
+
anObject_someArray_2: true,
|
|
142
|
+
anObject_someArray_3: false,
|
|
143
|
+
anObject_someArray_4_id: 'object id',
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('handles arrays nested in arrays correctly', () => {
|
|
148
|
+
const result = metrics.prepareMetricFields({
|
|
149
|
+
something: 10,
|
|
150
|
+
topLevelArray: [
|
|
151
|
+
[1, 2, 'three', {prop1: '1st prop of object 1', prop2: '2nd prop of object 1'}],
|
|
152
|
+
[10, 20, 'thirty', {prop1: '1st prop of object 2', prop2: '2nd prop of object 2'}],
|
|
153
|
+
],
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
assert.deepEqual(result, {
|
|
157
|
+
something: 10,
|
|
158
|
+
topLevelArray_0_0: 1,
|
|
159
|
+
topLevelArray_0_1: 2,
|
|
160
|
+
topLevelArray_0_2: 'three',
|
|
161
|
+
topLevelArray_0_3_prop1: '1st prop of object 1',
|
|
162
|
+
topLevelArray_0_3_prop2: '2nd prop of object 1',
|
|
163
|
+
topLevelArray_1_0: 10,
|
|
164
|
+
topLevelArray_1_1: 20,
|
|
165
|
+
topLevelArray_1_2: 'thirty',
|
|
166
|
+
topLevelArray_1_3_prop1: '1st prop of object 2',
|
|
167
|
+
topLevelArray_1_3_prop2: '2nd prop of object 2',
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('prepends the prefix', () => {
|
|
172
|
+
const result = metrics.prepareMetricFields({
|
|
173
|
+
someStringProp: 'a string',
|
|
174
|
+
numberProp: 111,
|
|
175
|
+
booleanPropFalse: false,
|
|
176
|
+
booleanPropTrue: true,
|
|
177
|
+
}, 'testPrefix');
|
|
178
|
+
|
|
179
|
+
assert.deepEqual(result, {
|
|
180
|
+
testPrefix_someStringProp: 'a string',
|
|
181
|
+
testPrefix_numberProp: 111,
|
|
182
|
+
testPrefix_booleanPropFalse: false,
|
|
183
|
+
testPrefix_booleanPropTrue: true,
|
|
184
|
+
});
|
|
185
|
+
})
|
|
186
|
+
});
|
|
61
187
|
});
|
|
@@ -4,7 +4,7 @@ import sinon from 'sinon';
|
|
|
4
4
|
import {assert} from '@webex/test-helper-chai';
|
|
5
5
|
import {getMaxFs} from '@webex/plugin-meetings/src/multistream/remoteMedia';
|
|
6
6
|
import FakeTimers from '@sinonjs/fake-timers';
|
|
7
|
-
import * as
|
|
7
|
+
import * as InternalMediaCoreModule from '@webex/internal-media-core';
|
|
8
8
|
import { expect } from 'chai';
|
|
9
9
|
|
|
10
10
|
type ExpectedActiveSpeaker = {
|
|
@@ -978,7 +978,7 @@ describe('MediaRequestManager', () => {
|
|
|
978
978
|
beforeEach(() => {
|
|
979
979
|
sendMediaRequestsCallback.resetHistory();
|
|
980
980
|
getRecommendedMaxBitrateForFrameSizeSpy = sinon.spy(
|
|
981
|
-
|
|
981
|
+
InternalMediaCoreModule,
|
|
982
982
|
'getRecommendedMaxBitrateForFrameSize'
|
|
983
983
|
);
|
|
984
984
|
});
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import 'jsdom-global/register';
|
|
6
6
|
import {assert} from '@webex/test-helper-chai';
|
|
7
7
|
import sinon from 'sinon';
|
|
8
|
-
import {
|
|
8
|
+
import {DESTINATION_TYPE} from '@webex/plugin-meetings/src/constants';
|
|
9
9
|
import PersonalMeetingRoom from '@webex/plugin-meetings/src/personal-meeting-room';
|
|
10
10
|
|
|
11
11
|
describe('personal-meeting-room', () => {
|
|
@@ -23,7 +23,7 @@ describe('personal-meeting-room', () => {
|
|
|
23
23
|
it('returns personal meeting room info', async () => {
|
|
24
24
|
await pmr.get();
|
|
25
25
|
assert.calledOnce(meetingInfo.fetchMeetingInfo);
|
|
26
|
-
assert.calledWith(meetingInfo.fetchMeetingInfo, {type:
|
|
26
|
+
assert.calledWith(meetingInfo.fetchMeetingInfo, {type: DESTINATION_TYPE.PERSONAL_ROOM});
|
|
27
27
|
});
|
|
28
28
|
});
|
|
29
29
|
});
|
|
@@ -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({
|