@webex/plugin-meetings 3.1.0 → 3.2.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/common/errors/reconnection-not-started.js +46 -0
- package/dist/common/errors/reconnection-not-started.js.map +1 -0
- package/dist/constants.js +16 -5
- package/dist/constants.js.map +1 -1
- package/dist/index.js +80 -0
- package/dist/index.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +7 -1
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +10 -0
- package/dist/locus-info/index.js.map +1 -1
- package/dist/media/properties.js +102 -57
- package/dist/media/properties.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js +10 -10
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +6 -0
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +564 -475
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +27 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/util.js +9 -16
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting/voicea-meeting.js +37 -49
- package/dist/meeting/voicea-meeting.js.map +1 -1
- package/dist/meeting-info/util.js +304 -267
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +334 -298
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/index.js +12 -28
- package/dist/meetings/index.js.map +1 -1
- package/dist/reachability/index.js +88 -9
- package/dist/reachability/index.js.map +1 -1
- package/dist/reconnection-manager/index.js +138 -109
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/request.js +3 -27
- package/dist/roap/request.js.map +1 -1
- package/dist/statsAnalyzer/index.js +8 -2
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +17 -0
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/annotation/annotation.types.d.ts +42 -0
- package/dist/types/annotation/constants.d.ts +31 -0
- package/dist/types/annotation/index.d.ts +117 -0
- package/dist/types/breakouts/breakout.d.ts +8 -0
- package/dist/types/breakouts/collection.d.ts +5 -0
- package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
- package/dist/types/breakouts/events.d.ts +8 -0
- package/dist/types/breakouts/index.d.ts +5 -0
- package/dist/types/breakouts/request.d.ts +22 -0
- package/dist/types/breakouts/utils.d.ts +15 -0
- package/dist/types/common/browser-detection.d.ts +9 -0
- package/dist/types/common/collection.d.ts +48 -0
- package/dist/types/common/config.d.ts +2 -0
- package/dist/types/common/errors/captcha-error.d.ts +15 -0
- package/dist/types/common/errors/intent-to-join.d.ts +16 -0
- package/dist/types/common/errors/join-meeting.d.ts +17 -0
- package/dist/types/common/errors/media.d.ts +15 -0
- package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/types/common/errors/parameter.d.ts +15 -0
- package/dist/types/common/errors/password-error.d.ts +15 -0
- package/dist/types/common/errors/permission.d.ts +14 -0
- package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/types/common/errors/reconnection-not-started.d.ts +13 -0
- package/dist/types/common/errors/reconnection.d.ts +15 -0
- package/dist/types/common/errors/stats.d.ts +15 -0
- package/dist/types/common/errors/webex-errors.d.ts +93 -0
- package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
- package/dist/types/common/events/events-scope.d.ts +17 -0
- package/dist/types/common/events/events.d.ts +12 -0
- package/dist/types/common/events/trigger-proxy.d.ts +2 -0
- package/dist/types/common/events/util.d.ts +2 -0
- package/dist/types/common/logs/logger-config.d.ts +2 -0
- package/dist/types/common/logs/logger-proxy.d.ts +2 -0
- package/dist/types/common/logs/request.d.ts +36 -0
- package/dist/types/common/queue.d.ts +34 -0
- package/dist/types/config.d.ts +73 -0
- package/dist/types/constants.d.ts +1098 -0
- package/dist/types/controls-options-manager/constants.d.ts +4 -0
- package/dist/types/controls-options-manager/enums.d.ts +15 -0
- package/dist/types/controls-options-manager/index.d.ts +136 -0
- package/dist/types/controls-options-manager/types.d.ts +43 -0
- package/dist/types/controls-options-manager/util.d.ts +1 -0
- package/dist/types/index.d.ts +19 -0
- package/dist/types/interceptors/index.d.ts +2 -0
- package/dist/types/interceptors/locusRetry.d.ts +27 -0
- package/dist/types/interpretation/collection.d.ts +5 -0
- package/dist/types/interpretation/index.d.ts +5 -0
- package/dist/types/interpretation/siLanguage.d.ts +5 -0
- package/dist/types/locus-info/controlsUtils.d.ts +2 -0
- package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
- package/dist/types/locus-info/fullState.d.ts +2 -0
- package/dist/types/locus-info/hostUtils.d.ts +2 -0
- package/dist/types/locus-info/index.d.ts +322 -0
- package/dist/types/locus-info/infoUtils.d.ts +2 -0
- package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
- package/dist/types/locus-info/parser.d.ts +272 -0
- package/dist/types/locus-info/selfUtils.d.ts +2 -0
- package/dist/types/media/MediaConnectionAwaiter.d.ts +61 -0
- package/dist/types/media/index.d.ts +34 -0
- package/dist/types/media/properties.d.ts +117 -0
- package/dist/types/media/util.d.ts +2 -0
- package/dist/types/mediaQualityMetrics/config.d.ts +247 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +173 -0
- package/dist/types/meeting/index.d.ts +1832 -0
- package/dist/types/meeting/locusMediaRequest.d.ts +75 -0
- package/dist/types/meeting/muteState.d.ts +178 -0
- package/dist/types/meeting/request.d.ts +295 -0
- package/dist/types/meeting/request.type.d.ts +11 -0
- package/dist/types/meeting/state.d.ts +9 -0
- package/dist/types/meeting/util.d.ts +122 -0
- package/dist/types/meeting/voicea-meeting.d.ts +17 -0
- package/dist/types/meeting-info/collection.d.ts +20 -0
- package/dist/types/meeting-info/index.d.ts +69 -0
- package/dist/types/meeting-info/meeting-info-v2.d.ts +123 -0
- package/dist/types/meeting-info/request.d.ts +22 -0
- package/dist/types/meeting-info/util.d.ts +49 -0
- package/dist/types/meeting-info/utilv2.d.ts +65 -0
- package/dist/types/meetings/collection.d.ts +40 -0
- package/dist/types/meetings/index.d.ts +383 -0
- package/dist/types/meetings/meetings.types.d.ts +4 -0
- package/dist/types/meetings/request.d.ts +27 -0
- package/dist/types/meetings/util.d.ts +18 -0
- package/dist/types/member/index.d.ts +160 -0
- package/dist/types/member/types.d.ts +32 -0
- package/dist/types/member/util.d.ts +2 -0
- package/dist/types/members/collection.d.ts +29 -0
- package/dist/types/members/index.d.ts +353 -0
- package/dist/types/members/request.d.ts +114 -0
- package/dist/types/members/types.d.ts +25 -0
- package/dist/types/members/util.d.ts +215 -0
- package/dist/types/metrics/constants.d.ts +70 -0
- package/dist/types/metrics/index.d.ts +45 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +119 -0
- package/dist/types/multistream/receiveSlot.d.ts +68 -0
- package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
- package/dist/types/multistream/remoteMedia.d.ts +72 -0
- package/dist/types/multistream/remoteMediaGroup.d.ts +49 -0
- package/dist/types/multistream/remoteMediaManager.d.ts +300 -0
- package/dist/types/multistream/sendSlotManager.d.ts +69 -0
- package/dist/types/networkQualityMonitor/index.d.ts +70 -0
- package/dist/types/personal-meeting-room/index.d.ts +47 -0
- package/dist/types/personal-meeting-room/request.d.ts +14 -0
- package/dist/types/personal-meeting-room/util.d.ts +2 -0
- package/dist/types/reachability/clusterReachability.d.ts +110 -0
- package/dist/types/reachability/index.d.ts +120 -0
- package/dist/types/reachability/request.d.ts +39 -0
- package/dist/types/reachability/util.d.ts +15 -0
- package/dist/types/reactions/constants.d.ts +3 -0
- package/dist/types/reactions/reactions.d.ts +4 -0
- package/dist/types/reactions/reactions.type.d.ts +52 -0
- package/dist/types/reconnection-manager/index.d.ts +126 -0
- package/dist/types/recording-controller/enums.d.ts +7 -0
- package/dist/types/recording-controller/index.d.ts +207 -0
- package/dist/types/recording-controller/util.d.ts +14 -0
- package/dist/types/roap/index.d.ts +86 -0
- package/dist/types/roap/request.d.ts +39 -0
- package/dist/types/roap/turnDiscovery.d.ts +155 -0
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +61 -0
- package/dist/types/statsAnalyzer/global.d.ts +36 -0
- package/dist/types/statsAnalyzer/index.d.ts +217 -0
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +48 -0
- package/dist/types/transcription/index.d.ts +64 -0
- package/dist/types/webinar/collection.d.ts +16 -0
- package/dist/types/webinar/index.d.ts +5 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/common/errors/reconnection-not-started.ts +25 -0
- package/src/constants.ts +14 -5
- package/src/index.ts +30 -0
- package/src/locus-info/controlsUtils.ts +11 -0
- package/src/locus-info/index.ts +16 -0
- package/src/media/properties.ts +67 -15
- package/src/mediaQualityMetrics/config.ts +13 -7
- package/src/meeting/in-meeting-actions.ts +12 -0
- package/src/meeting/index.ts +144 -107
- package/src/meeting/locusMediaRequest.ts +31 -0
- package/src/meeting/util.ts +9 -16
- package/src/meeting/voicea-meeting.ts +44 -46
- package/src/meeting-info/util.ts +241 -233
- package/src/meeting-info/utilv2.ts +250 -244
- package/src/meetings/index.ts +15 -27
- package/src/reachability/index.ts +60 -0
- package/src/reconnection-manager/index.ts +128 -105
- package/src/roap/request.ts +1 -24
- package/src/statsAnalyzer/index.ts +10 -3
- package/src/statsAnalyzer/mqaUtil.ts +23 -0
- package/test/unit/spec/locus-info/controlsUtils.js +20 -0
- package/test/unit/spec/locus-info/index.js +21 -0
- package/test/unit/spec/media/properties.ts +145 -140
- package/test/unit/spec/meeting/in-meeting-actions.ts +6 -0
- package/test/unit/spec/meeting/index.js +271 -105
- package/test/unit/spec/meeting/locusMediaRequest.ts +49 -0
- package/test/unit/spec/meeting/utils.js +3 -10
- package/test/unit/spec/meeting/voicea-meeting.ts +5 -14
- package/test/unit/spec/meetings/index.js +59 -17
- package/test/unit/spec/reachability/index.ts +266 -0
- package/test/unit/spec/reconnection-manager/index.js +127 -39
- package/test/unit/spec/roap/request.ts +0 -37
- package/test/unit/spec/stats-analyzer/index.js +100 -8
- package/src/common/errors/reconnection-in-progress.ts +0 -8
|
@@ -141,6 +141,272 @@ describe('isAnyPublicClusterReachable', () => {
|
|
|
141
141
|
});
|
|
142
142
|
});
|
|
143
143
|
|
|
144
|
+
|
|
145
|
+
describe('isWebexMediaBackendUnreachable', () => {
|
|
146
|
+
let webex;
|
|
147
|
+
|
|
148
|
+
beforeEach(() => {
|
|
149
|
+
webex = new MockWebex();
|
|
150
|
+
|
|
151
|
+
sinon.stub(MeetingUtil, 'getIpVersion').returns(IP_VERSION.unknown);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
afterEach(() => {
|
|
155
|
+
sinon.restore();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const runCheck = async (mockStorage: any, expectedValue: boolean) => {
|
|
159
|
+
if (mockStorage) {
|
|
160
|
+
await webex.boundedStorage.put(
|
|
161
|
+
'Reachability',
|
|
162
|
+
'reachability.result',
|
|
163
|
+
JSON.stringify(mockStorage)
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
const reachability = new Reachability(webex);
|
|
167
|
+
|
|
168
|
+
const result = await reachability.isWebexMediaBackendUnreachable();
|
|
169
|
+
|
|
170
|
+
assert.equal(result, expectedValue);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
[
|
|
174
|
+
{
|
|
175
|
+
title: 'no clusters at all',
|
|
176
|
+
mockStorage: {},
|
|
177
|
+
expectedResult: false,
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
title: 'clusters without results',
|
|
181
|
+
mockStorage: {a: {}, b: {}},
|
|
182
|
+
expectedResult: false,
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
title: 'all clusters untested',
|
|
186
|
+
mockStorage: {
|
|
187
|
+
a: {udp: 'untested'},
|
|
188
|
+
b: {udp: 'untested', tcp: 'untested'},
|
|
189
|
+
},
|
|
190
|
+
expectedResult: false,
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
title: 'one cluster with udp reachable',
|
|
194
|
+
mockStorage: {x: {udp: {result: 'reachable'}, tcp: {result: 'unreachable'}}},
|
|
195
|
+
expectedResult: false,
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
title: 'one cluster with tcp reachable',
|
|
199
|
+
mockStorage: {x: {tcp: {result: 'reachable'}}},
|
|
200
|
+
expectedResult: false,
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
title: 'one cluster with xtls reachable',
|
|
204
|
+
mockStorage: {x: {xtls: {result: 'reachable'}}, y: {xtls: {result: 'unreachable'}}},
|
|
205
|
+
expectedResult: false,
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
title: 'multiple clusters with various protocols reachable',
|
|
209
|
+
mockStorage: {
|
|
210
|
+
a: {udp: {result: 'reachable'}, tcp: {result: 'reachable'}},
|
|
211
|
+
b: {udp: {result: 'unreachable'}, tcp: {result: 'reachable'}},
|
|
212
|
+
c: {tcp: {result: 'reachable'}},
|
|
213
|
+
d: {xtls: {result: 'reachable'}},
|
|
214
|
+
},
|
|
215
|
+
expectedResult: false,
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
title: 'multiple clusters with all protocols unreachable',
|
|
219
|
+
mockStorage: {
|
|
220
|
+
a: {
|
|
221
|
+
udp: {result: 'unreachable'},
|
|
222
|
+
tcp: {result: 'unreachable'},
|
|
223
|
+
xtls: {result: 'unreachable'},
|
|
224
|
+
},
|
|
225
|
+
b: {
|
|
226
|
+
udp: {result: 'unreachable'},
|
|
227
|
+
tcp: {result: 'unreachable'},
|
|
228
|
+
xtls: {result: 'unreachable'},
|
|
229
|
+
},
|
|
230
|
+
c: {
|
|
231
|
+
udp: {result: 'unreachable'},
|
|
232
|
+
tcp: {result: 'unreachable'},
|
|
233
|
+
xtls: {result: 'unreachable'},
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
expectedResult: true,
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
title: 'multiple clusters with UDP and TCP protocols unreachable, but TLS not tested',
|
|
240
|
+
mockStorage: {
|
|
241
|
+
a: {
|
|
242
|
+
udp: {result: 'unreachable'},
|
|
243
|
+
tcp: {result: 'unreachable'},
|
|
244
|
+
xtls: {result: 'untested'},
|
|
245
|
+
},
|
|
246
|
+
b: {
|
|
247
|
+
udp: {result: 'unreachable'},
|
|
248
|
+
tcp: {result: 'unreachable'},
|
|
249
|
+
xtls: {result: 'untested'},
|
|
250
|
+
},
|
|
251
|
+
c: {
|
|
252
|
+
udp: {result: 'unreachable'},
|
|
253
|
+
tcp: {result: 'unreachable'},
|
|
254
|
+
xtls: {result: 'untested'},
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
expectedResult: false,
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
title: 'multiple clusters with UDP and TCP protocols unreachable, but TLS missing',
|
|
261
|
+
mockStorage: {
|
|
262
|
+
a: {
|
|
263
|
+
udp: {result: 'unreachable'},
|
|
264
|
+
tcp: {result: 'unreachable'},
|
|
265
|
+
},
|
|
266
|
+
b: {
|
|
267
|
+
udp: {result: 'unreachable'},
|
|
268
|
+
tcp: {result: 'unreachable'},
|
|
269
|
+
},
|
|
270
|
+
c: {
|
|
271
|
+
udp: {result: 'unreachable'},
|
|
272
|
+
tcp: {result: 'unreachable'},
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
expectedResult: false,
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
title: 'multiple clusters with UDP and TLS protocols unreachable, but TCP not tested',
|
|
279
|
+
mockStorage: {
|
|
280
|
+
a: {
|
|
281
|
+
udp: {result: 'unreachable'},
|
|
282
|
+
tcp: {result: 'untested'},
|
|
283
|
+
xtls: {result: 'unreachable'},
|
|
284
|
+
},
|
|
285
|
+
b: {
|
|
286
|
+
udp: {result: 'unreachable'},
|
|
287
|
+
tcp: {result: 'untested'},
|
|
288
|
+
xtls: {result: 'unreachable'},
|
|
289
|
+
},
|
|
290
|
+
c: {
|
|
291
|
+
udp: {result: 'unreachable'},
|
|
292
|
+
tcp: {result: 'untested'},
|
|
293
|
+
xtls: {result: 'unreachable'},
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
expectedResult: false,
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
title: 'multiple clusters with UDP and TLS protocols unreachable, but TCP missing',
|
|
300
|
+
mockStorage: {
|
|
301
|
+
a: {
|
|
302
|
+
udp: {result: 'unreachable'},
|
|
303
|
+
xtls: {result: 'unreachable'},
|
|
304
|
+
},
|
|
305
|
+
b: {
|
|
306
|
+
udp: {result: 'unreachable'},
|
|
307
|
+
xtls: {result: 'unreachable'},
|
|
308
|
+
},
|
|
309
|
+
c: {
|
|
310
|
+
udp: {result: 'unreachable'},
|
|
311
|
+
xtls: {result: 'unreachable'},
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
expectedResult: false,
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
title: 'multiple clusters with all protocols unreachable, some untested',
|
|
318
|
+
mockStorage: {
|
|
319
|
+
a: {
|
|
320
|
+
udp: {result: 'unreachable'},
|
|
321
|
+
tcp: {result: 'unreachable'},
|
|
322
|
+
xtls: {result: 'unreachable'},
|
|
323
|
+
},
|
|
324
|
+
b: {udp: {result: 'unreachable'}, tcp: {result: 'untested'}, xtls: {result: 'unreachable'}},
|
|
325
|
+
c: {udp: {result: 'unreachable'}, tcp: {result: 'unreachable'}, xtls: {result: 'untested'}},
|
|
326
|
+
},
|
|
327
|
+
expectedResult: true,
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
title: 'multiple clusters with all protocols unreachable, except for 1 reachable on udp',
|
|
331
|
+
mockStorage: {
|
|
332
|
+
a: {
|
|
333
|
+
udp: {result: 'reachable'},
|
|
334
|
+
tcp: {result: 'unreachable'},
|
|
335
|
+
xtls: {result: 'unreachable'},
|
|
336
|
+
},
|
|
337
|
+
b: {
|
|
338
|
+
udp: {result: 'unreachable'},
|
|
339
|
+
tcp: {result: 'unreachable'},
|
|
340
|
+
xtls: {result: 'unreachable'},
|
|
341
|
+
},
|
|
342
|
+
c: {
|
|
343
|
+
udp: {result: 'unreachable'},
|
|
344
|
+
tcp: {result: 'unreachable'},
|
|
345
|
+
xtls: {result: 'unreachable'},
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
expectedResult: false,
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
title: 'multiple clusters with all protocols unreachable, except for 1 reachable on tcp',
|
|
352
|
+
mockStorage: {
|
|
353
|
+
a: {
|
|
354
|
+
udp: {result: 'unreachable'},
|
|
355
|
+
tcp: {result: 'unreachable'},
|
|
356
|
+
xtls: {result: 'unreachable'},
|
|
357
|
+
},
|
|
358
|
+
b: {
|
|
359
|
+
udp: {result: 'unreachable'},
|
|
360
|
+
tcp: {result: 'unreachable'},
|
|
361
|
+
xtls: {result: 'unreachable'},
|
|
362
|
+
},
|
|
363
|
+
c: {
|
|
364
|
+
udp: {result: 'unreachable'},
|
|
365
|
+
tcp: {result: 'reachable'},
|
|
366
|
+
xtls: {result: 'unreachable'},
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
expectedResult: false,
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
title: 'multiple clusters with all protocols unreachable, except for 1 reachable on xtls',
|
|
373
|
+
mockStorage: {
|
|
374
|
+
a: {
|
|
375
|
+
udp: {result: 'unreachable'},
|
|
376
|
+
tcp: {result: 'unreachable'},
|
|
377
|
+
xtls: {result: 'unreachable'},
|
|
378
|
+
},
|
|
379
|
+
b: {
|
|
380
|
+
udp: {result: 'unreachable'},
|
|
381
|
+
tcp: {result: 'unreachable'},
|
|
382
|
+
xtls: {result: 'reachable'},
|
|
383
|
+
},
|
|
384
|
+
c: {
|
|
385
|
+
udp: {result: 'unreachable'},
|
|
386
|
+
tcp: {result: 'unreachable'},
|
|
387
|
+
xtls: {result: 'unreachable'},
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
expectedResult: false,
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
title: 'multiple clusters with some missing results',
|
|
394
|
+
mockStorage: {
|
|
395
|
+
a: {udp: {result: 'unreachable'}},
|
|
396
|
+
b: {tcp: {result: 'unreachable'}},
|
|
397
|
+
c: {xtls: {result: 'unreachable'}},
|
|
398
|
+
d: {},
|
|
399
|
+
},
|
|
400
|
+
expectedResult: true,
|
|
401
|
+
},
|
|
402
|
+
].forEach(({mockStorage, expectedResult, title}) => {
|
|
403
|
+
it(`returns ${expectedResult} when ${title}`, async () => {
|
|
404
|
+
await runCheck(mockStorage, expectedResult);
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
|
|
144
410
|
describe('gatherReachability', () => {
|
|
145
411
|
let webex;
|
|
146
412
|
|
|
@@ -2,11 +2,14 @@ import 'jsdom-global/register';
|
|
|
2
2
|
import chai from 'chai';
|
|
3
3
|
import chaiAsPromised from 'chai-as-promised';
|
|
4
4
|
import sinon from 'sinon';
|
|
5
|
+
import {Defer} from '@webex/common';
|
|
5
6
|
import ReconnectionManager from '@webex/plugin-meetings/src/reconnection-manager';
|
|
7
|
+
import ReconnectionNotStartedError from '@webex/plugin-meetings/src/common/errors/reconnection-not-started';
|
|
8
|
+
import TriggerProxy from '@webex/plugin-meetings/src/common/events/trigger-proxy';
|
|
9
|
+
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
6
10
|
import { RECONNECTION } from '../../../../src/constants';
|
|
7
11
|
import LoggerProxy from '../../../../src/common/logs/logger-proxy';
|
|
8
12
|
import LoggerConfig from '../../../../src/common/logs/logger-config';
|
|
9
|
-
|
|
10
13
|
const {assert} = chai;
|
|
11
14
|
|
|
12
15
|
chai.use(chaiAsPromised);
|
|
@@ -14,18 +17,15 @@ sinon.assert.expose(chai.assert, {prefix: ''});
|
|
|
14
17
|
|
|
15
18
|
describe('plugin-meetings', () => {
|
|
16
19
|
describe('ReconnectionManager.reconnect', () => {
|
|
17
|
-
const sandbox = sinon.createSandbox();
|
|
18
20
|
let fakeMediaConnection;
|
|
19
21
|
let fakeMeeting;
|
|
20
22
|
let loggerSpy;
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
beforeEach(() => {
|
|
23
25
|
LoggerConfig.set({ enable: false });
|
|
24
26
|
LoggerProxy.set();
|
|
25
|
-
loggerSpy =
|
|
26
|
-
});
|
|
27
|
+
loggerSpy = sinon.spy(LoggerProxy.logger, 'info');
|
|
27
28
|
|
|
28
|
-
beforeEach(() => {
|
|
29
29
|
fakeMediaConnection = {
|
|
30
30
|
initiateOffer: sinon.stub().resolves({}),
|
|
31
31
|
reconnect: sinon.stub().resolves({}),
|
|
@@ -33,6 +33,7 @@ describe('plugin-meetings', () => {
|
|
|
33
33
|
fakeMeeting = {
|
|
34
34
|
closePeerConnections: sinon.stub().resolves({}),
|
|
35
35
|
createMediaConnection: sinon.stub().returns(fakeMediaConnection),
|
|
36
|
+
correlationId: 'correlationId',
|
|
36
37
|
config: {
|
|
37
38
|
reconnection: {
|
|
38
39
|
enabled: true,
|
|
@@ -47,6 +48,7 @@ describe('plugin-meetings', () => {
|
|
|
47
48
|
},
|
|
48
49
|
},
|
|
49
50
|
},
|
|
51
|
+
locusUrl: 'test/id',
|
|
50
52
|
mediaProperties: {
|
|
51
53
|
unsetPeerConnection: sinon.stub(),
|
|
52
54
|
webrtcMediaConnection: fakeMediaConnection,
|
|
@@ -83,11 +85,16 @@ describe('plugin-meetings', () => {
|
|
|
83
85
|
}
|
|
84
86
|
}
|
|
85
87
|
},
|
|
88
|
+
trigger: sinon.stub(),
|
|
86
89
|
};
|
|
90
|
+
|
|
91
|
+
sinon.stub(TriggerProxy, 'trigger').returns(true);
|
|
92
|
+
sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
87
93
|
});
|
|
88
94
|
|
|
89
95
|
afterEach(() => {
|
|
90
|
-
|
|
96
|
+
sinon.reset();
|
|
97
|
+
sinon.restore();
|
|
91
98
|
});
|
|
92
99
|
|
|
93
100
|
it('calls syncMeetings', async () => {
|
|
@@ -223,6 +230,99 @@ describe('plugin-meetings', () => {
|
|
|
223
230
|
});
|
|
224
231
|
}
|
|
225
232
|
});
|
|
233
|
+
|
|
234
|
+
it('sends the right metrics and events when succeeds', async () => {
|
|
235
|
+
const rm = new ReconnectionManager(fakeMeeting);
|
|
236
|
+
|
|
237
|
+
await rm.reconnect();
|
|
238
|
+
|
|
239
|
+
assert.calledWith(
|
|
240
|
+
TriggerProxy.trigger,
|
|
241
|
+
fakeMeeting,
|
|
242
|
+
{file: 'reconnection-manager/index', function: 'reconnect'},
|
|
243
|
+
'meeting:reconnectionSuccess'
|
|
244
|
+
);
|
|
245
|
+
assert.calledWithMatch(fakeMeeting.webex.internal.newMetrics.submitClientEvent, {
|
|
246
|
+
name: 'client.media.recovered',
|
|
247
|
+
payload: {
|
|
248
|
+
recoveredBy: 'new',
|
|
249
|
+
},
|
|
250
|
+
options: {
|
|
251
|
+
meetingId: fakeMeeting.id,
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
assert.equal(rm.status, RECONNECTION.STATE.DEFAULT_STATUS);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it('sends the right metrics and events when fails', async () => {
|
|
258
|
+
const rm = new ReconnectionManager(fakeMeeting);
|
|
259
|
+
|
|
260
|
+
sinon.stub(rm, 'executeReconnection').rejects(new Error('fake error'));
|
|
261
|
+
|
|
262
|
+
await assert.isRejected(rm.reconnect());
|
|
263
|
+
|
|
264
|
+
assert.calledWith(
|
|
265
|
+
TriggerProxy.trigger,
|
|
266
|
+
fakeMeeting,
|
|
267
|
+
{file: 'reconnection-manager/index', function: 'reconnect'},
|
|
268
|
+
'meeting:reconnectionFailure'
|
|
269
|
+
);
|
|
270
|
+
assert.calledWithMatch(fakeMeeting.webex.internal.newMetrics.submitClientEvent, {
|
|
271
|
+
name: 'client.call.aborted',
|
|
272
|
+
payload: {
|
|
273
|
+
errors: [
|
|
274
|
+
{
|
|
275
|
+
category: 'expected',
|
|
276
|
+
errorCode: 2008,
|
|
277
|
+
fatal: true,
|
|
278
|
+
name: 'media-engine',
|
|
279
|
+
shownToUser: false,
|
|
280
|
+
},
|
|
281
|
+
],
|
|
282
|
+
},
|
|
283
|
+
options: {
|
|
284
|
+
meetingId: fakeMeeting.id,
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
assert.calledWith(Metrics.sendBehavioralMetric, 'js_sdk_meeting_reconnect_failures', {
|
|
288
|
+
correlation_id: fakeMeeting.correlationId,
|
|
289
|
+
locus_id: 'id',
|
|
290
|
+
reason: 'fake error',
|
|
291
|
+
stack: sinon.match.any,
|
|
292
|
+
});
|
|
293
|
+
assert.equal(rm.status, RECONNECTION.STATE.DEFAULT_STATUS);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('throws ReconnectionNotStartedError if reconnection is already in progress', async () => {
|
|
297
|
+
const rm = new ReconnectionManager(fakeMeeting);
|
|
298
|
+
const defer = new Defer();
|
|
299
|
+
|
|
300
|
+
sinon.stub(rm, 'executeReconnection').returns(defer.promise);
|
|
301
|
+
|
|
302
|
+
rm.reconnect();
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
await rm.reconnect();
|
|
306
|
+
|
|
307
|
+
fail("rm.reconnect() should have thrown, but it hasn't");
|
|
308
|
+
} catch (e) {
|
|
309
|
+
assert.instanceOf(e, ReconnectionNotStartedError);
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it('throws ReconnectionNotStartedError if reconnection is disabled in config', async () => {
|
|
314
|
+
fakeMeeting.config.reconnection.enabled = false;
|
|
315
|
+
|
|
316
|
+
const rm = new ReconnectionManager(fakeMeeting);
|
|
317
|
+
|
|
318
|
+
try {
|
|
319
|
+
await rm.reconnect();
|
|
320
|
+
|
|
321
|
+
fail("rm.reconnect() should have thrown, but it hasn't");
|
|
322
|
+
} catch (e) {
|
|
323
|
+
assert.instanceOf(e, ReconnectionNotStartedError);
|
|
324
|
+
}
|
|
325
|
+
});
|
|
226
326
|
});
|
|
227
327
|
|
|
228
328
|
/**
|
|
@@ -316,29 +416,41 @@ describe('plugin-meetings', () => {
|
|
|
316
416
|
|
|
317
417
|
describe('waitForIceReconnect()', () => {
|
|
318
418
|
describe('when ice is marked as not disconnected', () => {
|
|
419
|
+
let clock;
|
|
420
|
+
|
|
319
421
|
beforeEach(() => {
|
|
422
|
+
clock = sinon.useFakeTimers();
|
|
320
423
|
reconnectionManager.iceState.disconnected = false;
|
|
321
424
|
});
|
|
322
425
|
|
|
426
|
+
afterEach(() => {
|
|
427
|
+
clock.restore();
|
|
428
|
+
});
|
|
429
|
+
|
|
323
430
|
it('should set the disconnected state to true', () => {
|
|
324
|
-
reconnectionManager.waitForIceReconnect();
|
|
431
|
+
const promise = reconnectionManager.waitForIceReconnect();
|
|
325
432
|
|
|
326
433
|
assert.isTrue(reconnectionManager.iceState.disconnected);
|
|
434
|
+
|
|
435
|
+
// we let the timer expire
|
|
436
|
+
clock.tick(reconnectionManager.iceState.timeoutDuration);
|
|
437
|
+
assert.isRejected(promise);
|
|
327
438
|
});
|
|
328
439
|
|
|
329
|
-
it('should return a promise that rejects after a duration', (
|
|
330
|
-
|
|
440
|
+
it('should return a promise that rejects after a duration', async () => {
|
|
441
|
+
const promise = reconnectionManager.waitForIceReconnect();
|
|
331
442
|
|
|
332
|
-
|
|
333
|
-
|
|
443
|
+
// we let the timer expire
|
|
444
|
+
clock.tick(reconnectionManager.iceState.timeoutDuration);
|
|
445
|
+
assert.isRejected(promise);
|
|
334
446
|
});
|
|
335
447
|
|
|
336
|
-
it('should resolve
|
|
448
|
+
it('should resolve when ICE is reconnected', async () => {
|
|
337
449
|
const promise = reconnectionManager.waitForIceReconnect();
|
|
338
450
|
|
|
339
|
-
reconnectionManager.
|
|
451
|
+
reconnectionManager.iceReconnected();
|
|
340
452
|
|
|
341
|
-
|
|
453
|
+
await promise;
|
|
342
454
|
});
|
|
343
455
|
});
|
|
344
456
|
|
|
@@ -359,30 +471,6 @@ describe('plugin-meetings', () => {
|
|
|
359
471
|
});
|
|
360
472
|
});
|
|
361
473
|
|
|
362
|
-
describe('setStatus()', () => {
|
|
363
|
-
beforeEach(() => {
|
|
364
|
-
reconnectionManager.status = RECONNECTION.STATE.DEFAULT_STATUS;
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
it('should correctly change status to in progress', () => {
|
|
368
|
-
reconnectionManager.setStatus(RECONNECTION.STATE.IN_PROGRESS);
|
|
369
|
-
|
|
370
|
-
assert.equal(reconnectionManager.status, RECONNECTION.STATE.IN_PROGRESS);
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
it('should correctly change status to complete', () => {
|
|
374
|
-
reconnectionManager.setStatus(RECONNECTION.STATE.COMPLETE);
|
|
375
|
-
|
|
376
|
-
assert.equal(reconnectionManager.status, RECONNECTION.STATE.COMPLETE);
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
it('should correctly change status to failure', () => {
|
|
380
|
-
reconnectionManager.setStatus(RECONNECTION.STATE.FAILURE);
|
|
381
|
-
|
|
382
|
-
assert.equal(reconnectionManager.status, RECONNECTION.STATE.FAILURE);
|
|
383
|
-
});
|
|
384
|
-
});
|
|
385
|
-
|
|
386
474
|
describe('cleanUp()', () => {
|
|
387
475
|
it('should call reset and keep reference to meeting object', () => {
|
|
388
476
|
const resetSpy = sinon.spy(reconnectionManager, 'reset');
|
|
@@ -133,20 +133,6 @@ describe('plugin-meetings/roap', () => {
|
|
|
133
133
|
locusMediaRequest,
|
|
134
134
|
});
|
|
135
135
|
|
|
136
|
-
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
137
|
-
name: 'client.locus.media.request',
|
|
138
|
-
options: {
|
|
139
|
-
meetingId: 'meeting-id',
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
144
|
-
name: 'client.locus.media.response',
|
|
145
|
-
options: {
|
|
146
|
-
meetingId: 'meeting-id',
|
|
147
|
-
},
|
|
148
|
-
});
|
|
149
|
-
|
|
150
136
|
const requestParams = locusMediaRequest.send.getCall(0).args[0];
|
|
151
137
|
assert.deepEqual(requestParams, {
|
|
152
138
|
type: 'RoapMessage',
|
|
@@ -175,29 +161,6 @@ describe('plugin-meetings/roap', () => {
|
|
|
175
161
|
},
|
|
176
162
|
});
|
|
177
163
|
});
|
|
178
|
-
|
|
179
|
-
it('sends correct client event when fails', async () => {
|
|
180
|
-
const locusMediaRequest = {send: sinon.stub().rejects({code: 300, message: 'error'})};
|
|
181
|
-
try {
|
|
182
|
-
await roapRequest.sendRoap({
|
|
183
|
-
locusSelfUrl: locusUrl,
|
|
184
|
-
mediaId: 'mediaId',
|
|
185
|
-
roapMessage: {
|
|
186
|
-
seq: 'seq',
|
|
187
|
-
},
|
|
188
|
-
meetingId: 'meeting-id',
|
|
189
|
-
locusMediaRequest,
|
|
190
|
-
});
|
|
191
|
-
} catch (err) {
|
|
192
|
-
assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
|
|
193
|
-
name: 'client.locus.media.response',
|
|
194
|
-
options: {
|
|
195
|
-
meetingId: 'meeting-id',
|
|
196
|
-
rawError: {code: 300, message: 'error'},
|
|
197
|
-
},
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
164
|
});
|
|
202
165
|
|
|
203
166
|
it('calls attachReachabilityData when sendRoap', async () => {
|