@webex/plugin-meetings 3.0.0-beta.281 → 3.0.0-beta.282
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 +6 -4
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/media/properties.js +1 -1
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/index.js +686 -425
- package/dist/meeting/index.js.map +1 -1
- package/dist/types/constants.d.ts +2 -1
- package/dist/types/meeting/index.d.ts +60 -1
- package/package.json +19 -19
- package/src/constants.ts +2 -1
- package/src/media/properties.ts +2 -2
- package/src/meeting/index.ts +404 -278
- package/test/unit/spec/media/properties.ts +2 -2
- package/test/unit/spec/meeting/index.js +206 -26
|
@@ -4,7 +4,7 @@ import {ConnectionState, Event} from '@webex/internal-media-core';
|
|
|
4
4
|
import MediaProperties from '@webex/plugin-meetings/src/media/properties';
|
|
5
5
|
import MediaUtil from '@webex/plugin-meetings/src/media/util';
|
|
6
6
|
import testUtils from '../../../utils/testUtils';
|
|
7
|
-
import {
|
|
7
|
+
import {ICE_AND_DTLS_CONNECTION_TIMEOUT} from '@webex/plugin-meetings/src/constants';
|
|
8
8
|
import {Defer} from '@webex/common';
|
|
9
9
|
|
|
10
10
|
describe('MediaProperties', () => {
|
|
@@ -52,7 +52,7 @@ describe('MediaProperties', () => {
|
|
|
52
52
|
assert.equal(promiseResolved, false);
|
|
53
53
|
assert.equal(promiseRejected, false);
|
|
54
54
|
|
|
55
|
-
await clock.tickAsync(
|
|
55
|
+
await clock.tickAsync(ICE_AND_DTLS_CONNECTION_TIMEOUT);
|
|
56
56
|
await testUtils.flushPromises();
|
|
57
57
|
|
|
58
58
|
assert.equal(promiseResolved, false);
|
|
@@ -25,12 +25,14 @@ import {
|
|
|
25
25
|
_MEETING_ID_,
|
|
26
26
|
MEETING_REMOVED_REASON,
|
|
27
27
|
LOCUSINFO,
|
|
28
|
-
|
|
28
|
+
ICE_AND_DTLS_CONNECTION_TIMEOUT,
|
|
29
29
|
DISPLAY_HINTS,
|
|
30
30
|
SELF_POLICY,
|
|
31
31
|
IP_VERSION,
|
|
32
32
|
ERROR_DICTIONARY,
|
|
33
33
|
NETWORK_STATUS,
|
|
34
|
+
ONLINE,
|
|
35
|
+
OFFLINE,
|
|
34
36
|
} from '@webex/plugin-meetings/src/constants';
|
|
35
37
|
import * as InternalMediaCoreModule from '@webex/internal-media-core';
|
|
36
38
|
import {
|
|
@@ -105,6 +107,7 @@ import {
|
|
|
105
107
|
} from '@webex/internal-plugin-metrics/src/call-diagnostic/config';
|
|
106
108
|
import CallDiagnosticMetrics from '@webex/internal-plugin-metrics/src/call-diagnostic/call-diagnostic-metrics';
|
|
107
109
|
import { ERROR_DESCRIPTIONS } from '@webex/internal-plugin-metrics/src/call-diagnostic/config';
|
|
110
|
+
import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
|
|
108
111
|
|
|
109
112
|
|
|
110
113
|
describe('plugin-meetings', () => {
|
|
@@ -1151,6 +1154,7 @@ describe('plugin-meetings', () => {
|
|
|
1151
1154
|
meeting.roap.doTurnDiscovery = sinon
|
|
1152
1155
|
.stub()
|
|
1153
1156
|
.resolves({turnServerInfo: {}, turnDiscoverySkippedReason: undefined});
|
|
1157
|
+
meeting.waitForRemoteSDPAnswer = sinon.stub().resolves();
|
|
1154
1158
|
});
|
|
1155
1159
|
|
|
1156
1160
|
it('should have #addMedia', () => {
|
|
@@ -1324,6 +1328,61 @@ describe('plugin-meetings', () => {
|
|
|
1324
1328
|
assert.isNull(meeting.mediaProperties.webrtcMediaConnection);
|
|
1325
1329
|
});
|
|
1326
1330
|
|
|
1331
|
+
it('should send metrics and reset the statsAnalyzer to null if waitForRemoteSDPAnswer fails', async () => {
|
|
1332
|
+
meeting.meetingState = 'ACTIVE';
|
|
1333
|
+
meeting.webex.meetings.reachability = {
|
|
1334
|
+
getReachabilityMetrics: sinon.stub().resolves({
|
|
1335
|
+
someReachabilityMetric1: 'some value1',
|
|
1336
|
+
someReachabilityMetric2: 'some value2',
|
|
1337
|
+
}),
|
|
1338
|
+
};
|
|
1339
|
+
|
|
1340
|
+
meeting.waitForRemoteSDPAnswer = sinon.stub().rejects();
|
|
1341
|
+
|
|
1342
|
+
// set a statsAnalyzer on the meeting so that we can check that it gets reset to null
|
|
1343
|
+
meeting.statsAnalyzer = {stopAnalyzer: sinon.stub().resolves()};
|
|
1344
|
+
|
|
1345
|
+
const error = await assert.isRejected(meeting.addMedia());
|
|
1346
|
+
|
|
1347
|
+
assert.isNull(meeting.statsAnalyzer);
|
|
1348
|
+
assert(webex.internal.newMetrics.submitInternalEvent.calledTwice);
|
|
1349
|
+
assert.calledWith(webex.internal.newMetrics.submitInternalEvent.firstCall, {
|
|
1350
|
+
name: 'internal.client.add-media.turn-discovery.start',
|
|
1351
|
+
});
|
|
1352
|
+
assert.calledWith(webex.internal.newMetrics.submitInternalEvent.secondCall, {
|
|
1353
|
+
name: 'internal.client.add-media.turn-discovery.end',
|
|
1354
|
+
});
|
|
1355
|
+
assert(Metrics.sendBehavioralMetric.calledTwice);
|
|
1356
|
+
assert.calledWith(
|
|
1357
|
+
Metrics.sendBehavioralMetric.firstCall,
|
|
1358
|
+
BEHAVIORAL_METRICS.TURN_DISCOVERY_LATENCY,
|
|
1359
|
+
{
|
|
1360
|
+
correlation_id: meeting.correlationId,
|
|
1361
|
+
turnServerUsed: true,
|
|
1362
|
+
latency: undefined,
|
|
1363
|
+
}
|
|
1364
|
+
);
|
|
1365
|
+
assert.calledWith(
|
|
1366
|
+
Metrics.sendBehavioralMetric.secondCall,
|
|
1367
|
+
BEHAVIORAL_METRICS.ADD_MEDIA_FAILURE,
|
|
1368
|
+
{
|
|
1369
|
+
correlation_id: meeting.correlationId,
|
|
1370
|
+
locus_id: meeting.locusUrl.split('/').pop(),
|
|
1371
|
+
reason: error.message,
|
|
1372
|
+
stack: error.stack,
|
|
1373
|
+
code: error.code,
|
|
1374
|
+
turnDiscoverySkippedReason: undefined,
|
|
1375
|
+
turnServerUsed: true,
|
|
1376
|
+
isMultistream: false,
|
|
1377
|
+
signalingState: 'unknown',
|
|
1378
|
+
connectionState: 'unknown',
|
|
1379
|
+
iceConnectionState: 'unknown',
|
|
1380
|
+
someReachabilityMetric1: 'some value1',
|
|
1381
|
+
someReachabilityMetric2: 'some value2',
|
|
1382
|
+
}
|
|
1383
|
+
);
|
|
1384
|
+
});
|
|
1385
|
+
|
|
1327
1386
|
it('should include the peer connection properties correctly for multistream', async () => {
|
|
1328
1387
|
meeting.meetingState = 'ACTIVE';
|
|
1329
1388
|
// setup the mock to return an incomplete object - this will cause addMedia to fail
|
|
@@ -1606,10 +1665,7 @@ describe('plugin-meetings', () => {
|
|
|
1606
1665
|
mediaSettings: {},
|
|
1607
1666
|
});
|
|
1608
1667
|
|
|
1609
|
-
await clock.tickAsync(
|
|
1610
|
-
4000 /* meetingState timer, hardcoded inside addMedia */ +
|
|
1611
|
-
PC_BAIL_TIMEOUT /* connection state timer */
|
|
1612
|
-
);
|
|
1668
|
+
await clock.tickAsync(ICE_AND_DTLS_CONNECTION_TIMEOUT);
|
|
1613
1669
|
await testUtils.flushPromises();
|
|
1614
1670
|
|
|
1615
1671
|
assert.exists(media);
|
|
@@ -2030,6 +2086,7 @@ describe('plugin-meetings', () => {
|
|
|
2030
2086
|
let locusMediaRequestStub; // stub for /media requests to Locus
|
|
2031
2087
|
|
|
2032
2088
|
const roapOfferMessage = {messageType: 'OFFER', sdp: 'sdp', seq: '1', tieBreaker: '123'};
|
|
2089
|
+
const roapOKMessage = {messageType: 'OK', seq: '1'};
|
|
2033
2090
|
|
|
2034
2091
|
let expectedMediaConnectionConfig;
|
|
2035
2092
|
let expectedDebugId;
|
|
@@ -2037,7 +2094,7 @@ describe('plugin-meetings', () => {
|
|
|
2037
2094
|
let clock;
|
|
2038
2095
|
|
|
2039
2096
|
beforeEach(() => {
|
|
2040
|
-
clock = sinon.useFakeTimers();
|
|
2097
|
+
clock = sinon.useFakeTimers();
|
|
2041
2098
|
|
|
2042
2099
|
sinon.stub(MeetingUtil, 'getIpVersion').returns(IP_VERSION.unknown);
|
|
2043
2100
|
|
|
@@ -2055,6 +2112,10 @@ describe('plugin-meetings', () => {
|
|
|
2055
2112
|
meeting.roap.doTurnDiscovery = sinon
|
|
2056
2113
|
.stub()
|
|
2057
2114
|
.resolves({turnServerInfo: {}, turnDiscoverySkippedReason: 'reachability'});
|
|
2115
|
+
meeting.deferSDPAnswer = new Defer();
|
|
2116
|
+
meeting.deferSDPAnswer.resolve();
|
|
2117
|
+
meeting.webex.meetings.meetingCollection = new MeetingCollection();
|
|
2118
|
+
meeting.webex.meetings.meetingCollection.set(meeting);
|
|
2058
2119
|
|
|
2059
2120
|
StaticConfig.set({bandwidth: {audio: 1234, video: 5678, startBitrate: 9876}});
|
|
2060
2121
|
|
|
@@ -2164,12 +2225,21 @@ describe('plugin-meetings', () => {
|
|
|
2164
2225
|
|
|
2165
2226
|
// simulates a Roap offer being generated by the RoapMediaConnection
|
|
2166
2227
|
const simulateRoapOffer = async () => {
|
|
2228
|
+
meeting.deferSDPAnswer = {resolve: sinon.stub()};
|
|
2167
2229
|
const roapListener = getRoapListener();
|
|
2168
2230
|
|
|
2169
2231
|
await roapListener({roapMessage: roapOfferMessage});
|
|
2170
2232
|
await stableState();
|
|
2171
2233
|
};
|
|
2172
2234
|
|
|
2235
|
+
// simulates a Roap OK being sent
|
|
2236
|
+
const simulateRoapOk = async () => {
|
|
2237
|
+
const roapListener = getRoapListener();
|
|
2238
|
+
|
|
2239
|
+
await roapListener({roapMessage: roapOKMessage});
|
|
2240
|
+
await stableState();
|
|
2241
|
+
};
|
|
2242
|
+
|
|
2173
2243
|
const checkSdpOfferSent = ({audioMuted, videoMuted}) => {
|
|
2174
2244
|
const {sdp, seq, tieBreaker} = roapOfferMessage;
|
|
2175
2245
|
|
|
@@ -2199,6 +2269,35 @@ describe('plugin-meetings', () => {
|
|
|
2199
2269
|
});
|
|
2200
2270
|
};
|
|
2201
2271
|
|
|
2272
|
+
const checkOkSent = ({audioMuted, videoMuted}) => {
|
|
2273
|
+
const {seq} = roapOKMessage;
|
|
2274
|
+
|
|
2275
|
+
assert.calledWith(locusMediaRequestStub, {
|
|
2276
|
+
method: 'PUT',
|
|
2277
|
+
uri: `${meeting.selfUrl}/media`,
|
|
2278
|
+
body: {
|
|
2279
|
+
device: {
|
|
2280
|
+
url: meeting.deviceUrl,
|
|
2281
|
+
deviceType: meeting.config.deviceType,
|
|
2282
|
+
countryCode: 'UK',
|
|
2283
|
+
regionCode: 'EU'
|
|
2284
|
+
},
|
|
2285
|
+
correlationId: meeting.correlationId,
|
|
2286
|
+
clientMediaPreferences: {
|
|
2287
|
+
preferTranscoding: !meeting.isMultistream,
|
|
2288
|
+
ipver: undefined,
|
|
2289
|
+
joinCookie: undefined
|
|
2290
|
+
},
|
|
2291
|
+
localMedias: [
|
|
2292
|
+
{
|
|
2293
|
+
localSdp: `{"audioMuted":${audioMuted},"videoMuted":${videoMuted},"roapMessage":{"messageType":"OK","version":"2","seq":"${seq}"}}`,
|
|
2294
|
+
mediaId: 'fake media id'
|
|
2295
|
+
},
|
|
2296
|
+
],
|
|
2297
|
+
},
|
|
2298
|
+
});
|
|
2299
|
+
};
|
|
2300
|
+
|
|
2202
2301
|
const checkLocalMuteSentToLocus = ({audioMuted, videoMuted}) => {
|
|
2203
2302
|
assert.calledWith(locusMediaRequestStub, {
|
|
2204
2303
|
method: 'PUT',
|
|
@@ -2279,6 +2378,7 @@ describe('plugin-meetings', () => {
|
|
|
2279
2378
|
it('addMedia() works correctly when media is enabled without tracks to publish', async () => {
|
|
2280
2379
|
await meeting.addMedia();
|
|
2281
2380
|
await simulateRoapOffer();
|
|
2381
|
+
await simulateRoapOk();
|
|
2282
2382
|
|
|
2283
2383
|
// check RoapMediaConnection was created correctly
|
|
2284
2384
|
checkMediaConnectionCreated({
|
|
@@ -2301,14 +2401,17 @@ describe('plugin-meetings', () => {
|
|
|
2301
2401
|
|
|
2302
2402
|
// and SDP offer was sent with the right audioMuted/videoMuted values
|
|
2303
2403
|
checkSdpOfferSent({audioMuted: true, videoMuted: true});
|
|
2404
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
2405
|
+
checkOkSent({audioMuted: true, videoMuted: true});
|
|
2304
2406
|
|
|
2305
|
-
// and that
|
|
2306
|
-
assert.
|
|
2407
|
+
// and that these were the only /media requests that were sent
|
|
2408
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
2307
2409
|
});
|
|
2308
2410
|
|
|
2309
2411
|
it('addMedia() works correctly when media is enabled with streams to publish', async () => {
|
|
2310
2412
|
await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
|
|
2311
2413
|
await simulateRoapOffer();
|
|
2414
|
+
await simulateRoapOk();
|
|
2312
2415
|
|
|
2313
2416
|
// check RoapMediaConnection was created correctly
|
|
2314
2417
|
checkMediaConnectionCreated({
|
|
@@ -2331,9 +2434,11 @@ describe('plugin-meetings', () => {
|
|
|
2331
2434
|
|
|
2332
2435
|
// and SDP offer was sent with the right audioMuted/videoMuted values
|
|
2333
2436
|
checkSdpOfferSent({audioMuted: false, videoMuted: true});
|
|
2437
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
2438
|
+
checkOkSent({audioMuted: false, videoMuted: true});
|
|
2334
2439
|
|
|
2335
|
-
// and
|
|
2336
|
-
assert.
|
|
2440
|
+
// and that these were the only /media requests that were sent
|
|
2441
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
2337
2442
|
});
|
|
2338
2443
|
|
|
2339
2444
|
it('addMedia() works correctly when media is enabled with tracks to publish and track is muted', async () => {
|
|
@@ -2341,6 +2446,7 @@ describe('plugin-meetings', () => {
|
|
|
2341
2446
|
|
|
2342
2447
|
await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}});
|
|
2343
2448
|
await simulateRoapOffer();
|
|
2449
|
+
await simulateRoapOk();
|
|
2344
2450
|
|
|
2345
2451
|
// check RoapMediaConnection was created correctly
|
|
2346
2452
|
checkMediaConnectionCreated({
|
|
@@ -2362,14 +2468,17 @@ describe('plugin-meetings', () => {
|
|
|
2362
2468
|
});
|
|
2363
2469
|
// and SDP offer was sent with the right audioMuted/videoMuted values
|
|
2364
2470
|
checkSdpOfferSent({audioMuted: true, videoMuted: true});
|
|
2471
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
2472
|
+
checkOkSent({audioMuted: true, videoMuted: true});
|
|
2365
2473
|
|
|
2366
|
-
// and
|
|
2367
|
-
assert.
|
|
2474
|
+
// and that these were the only /media requests that were sent
|
|
2475
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
2368
2476
|
});
|
|
2369
2477
|
|
|
2370
2478
|
it('addMedia() works correctly when media is disabled with tracks to publish', async () => {
|
|
2371
2479
|
await meeting.addMedia({localStreams: {microphone: fakeMicrophoneStream}, audioEnabled: false});
|
|
2372
2480
|
await simulateRoapOffer();
|
|
2481
|
+
await simulateRoapOk();
|
|
2373
2482
|
|
|
2374
2483
|
// check RoapMediaConnection was created correctly
|
|
2375
2484
|
checkMediaConnectionCreated({
|
|
@@ -2392,14 +2501,17 @@ describe('plugin-meetings', () => {
|
|
|
2392
2501
|
|
|
2393
2502
|
// and SDP offer was sent with the right audioMuted/videoMuted values
|
|
2394
2503
|
checkSdpOfferSent({audioMuted: true, videoMuted: true});
|
|
2504
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
2505
|
+
checkOkSent({audioMuted: true, videoMuted: true});
|
|
2395
2506
|
|
|
2396
|
-
// and
|
|
2397
|
-
assert.
|
|
2507
|
+
// and that these were the only /media requests that were sent
|
|
2508
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
2398
2509
|
});
|
|
2399
2510
|
|
|
2400
2511
|
it('addMedia() works correctly when media is disabled with no tracks to publish', async () => {
|
|
2401
2512
|
await meeting.addMedia({audioEnabled: false});
|
|
2402
2513
|
await simulateRoapOffer();
|
|
2514
|
+
await simulateRoapOk();
|
|
2403
2515
|
|
|
2404
2516
|
// check RoapMediaConnection was created correctly
|
|
2405
2517
|
checkMediaConnectionCreated({
|
|
@@ -2422,15 +2534,18 @@ describe('plugin-meetings', () => {
|
|
|
2422
2534
|
|
|
2423
2535
|
// and SDP offer was sent with the right audioMuted/videoMuted values
|
|
2424
2536
|
checkSdpOfferSent({audioMuted: true, videoMuted: true});
|
|
2537
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
2538
|
+
checkOkSent({audioMuted: true, videoMuted: true});
|
|
2425
2539
|
|
|
2426
|
-
// and
|
|
2427
|
-
assert.
|
|
2540
|
+
// and that these were the only /media requests that were sent
|
|
2541
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
2428
2542
|
});
|
|
2429
2543
|
|
|
2430
2544
|
|
|
2431
2545
|
it('addMedia() works correctly when video is disabled with no tracks to publish', async () => {
|
|
2432
2546
|
await meeting.addMedia({videoEnabled: false});
|
|
2433
2547
|
await simulateRoapOffer();
|
|
2548
|
+
await simulateRoapOk();
|
|
2434
2549
|
|
|
2435
2550
|
// check RoapMediaConnection was created correctly
|
|
2436
2551
|
checkMediaConnectionCreated({
|
|
@@ -2453,14 +2568,18 @@ describe('plugin-meetings', () => {
|
|
|
2453
2568
|
|
|
2454
2569
|
// and SDP offer was sent with the right audioMuted/videoMuted values
|
|
2455
2570
|
checkSdpOfferSent({audioMuted: true, videoMuted: true});
|
|
2571
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
2572
|
+
checkOkSent({audioMuted: true, videoMuted: true});
|
|
2456
2573
|
|
|
2457
|
-
// and
|
|
2458
|
-
assert.
|
|
2574
|
+
// and that these were the only /media requests that were sent
|
|
2575
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
2459
2576
|
});
|
|
2460
2577
|
|
|
2461
2578
|
it('addMedia() works correctly when screen share is disabled with no tracks to publish', async () => {
|
|
2462
2579
|
await meeting.addMedia({shareAudioEnabled: false, shareVideoEnabled: false});
|
|
2463
2580
|
await simulateRoapOffer();
|
|
2581
|
+
await simulateRoapOk();
|
|
2582
|
+
|
|
2464
2583
|
|
|
2465
2584
|
// check RoapMediaConnection was created correctly
|
|
2466
2585
|
checkMediaConnectionCreated({
|
|
@@ -2483,9 +2602,11 @@ describe('plugin-meetings', () => {
|
|
|
2483
2602
|
|
|
2484
2603
|
// and SDP offer was sent with the right audioMuted/videoMuted values
|
|
2485
2604
|
checkSdpOfferSent({audioMuted: true, videoMuted: true});
|
|
2605
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
2606
|
+
checkOkSent({audioMuted: true, videoMuted: true});
|
|
2486
2607
|
|
|
2487
|
-
// and
|
|
2488
|
-
assert.
|
|
2608
|
+
// and that these were the only /media requests that were sent
|
|
2609
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
2489
2610
|
});
|
|
2490
2611
|
|
|
2491
2612
|
describe('publishStreams()/unpublishStreams() calls', () => {
|
|
@@ -2497,6 +2618,7 @@ describe('plugin-meetings', () => {
|
|
|
2497
2618
|
it(`first publishStreams() call while media is ${mediaEnabled ? 'enabled' : 'disabled'}`, async () => {
|
|
2498
2619
|
await meeting.addMedia({audioEnabled: mediaEnabled});
|
|
2499
2620
|
await simulateRoapOffer();
|
|
2621
|
+
await simulateRoapOk();
|
|
2500
2622
|
|
|
2501
2623
|
resetHistory();
|
|
2502
2624
|
|
|
@@ -2532,6 +2654,7 @@ describe('plugin-meetings', () => {
|
|
|
2532
2654
|
it(`second publishStreams() call while media is ${mediaEnabled ? 'enabled' : 'disabled'}`, async () => {
|
|
2533
2655
|
await meeting.addMedia({audioEnabled: mediaEnabled});
|
|
2534
2656
|
await simulateRoapOffer();
|
|
2657
|
+
await simulateRoapOk();
|
|
2535
2658
|
await meeting.publishStreams({microphone: fakeMicrophoneStream});
|
|
2536
2659
|
await stableState();
|
|
2537
2660
|
|
|
@@ -2573,6 +2696,7 @@ describe('plugin-meetings', () => {
|
|
|
2573
2696
|
it(`unpublishStreams() call while media is ${mediaEnabled ? 'enabled' : 'disabled'}`, async () => {
|
|
2574
2697
|
await meeting.addMedia({audioEnabled: mediaEnabled});
|
|
2575
2698
|
await simulateRoapOffer();
|
|
2699
|
+
await simulateRoapOk();
|
|
2576
2700
|
await meeting.publishStreams({microphone: fakeMicrophoneStream});
|
|
2577
2701
|
await stableState();
|
|
2578
2702
|
|
|
@@ -2616,6 +2740,7 @@ describe('plugin-meetings', () => {
|
|
|
2616
2740
|
const addMedia = async (enableMedia, stream) => {
|
|
2617
2741
|
await meeting.addMedia({audioEnabled: enableMedia, localStreams: {microphone: stream}});
|
|
2618
2742
|
await simulateRoapOffer();
|
|
2743
|
+
await simulateRoapOk();
|
|
2619
2744
|
|
|
2620
2745
|
resetHistory();
|
|
2621
2746
|
}
|
|
@@ -2650,8 +2775,14 @@ describe('plugin-meetings', () => {
|
|
|
2650
2775
|
// check SDP offer was sent with the right audioMuted/videoMuted values
|
|
2651
2776
|
checkSdpOfferSent({audioMuted: true, videoMuted: true});
|
|
2652
2777
|
|
|
2778
|
+
// simulate OK being sent in response to remote answer being received
|
|
2779
|
+
await simulateRoapOk();
|
|
2780
|
+
|
|
2781
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
2782
|
+
checkOkSent({audioMuted: true, videoMuted: true});
|
|
2783
|
+
|
|
2653
2784
|
// and no other local mute requests were sent to Locus
|
|
2654
|
-
assert.
|
|
2785
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
2655
2786
|
});
|
|
2656
2787
|
|
|
2657
2788
|
it('updateMedia() enables media when nothing is published', async () => {
|
|
@@ -2668,8 +2799,14 @@ describe('plugin-meetings', () => {
|
|
|
2668
2799
|
// check SDP offer was sent with the right audioMuted/videoMuted values
|
|
2669
2800
|
checkSdpOfferSent({audioMuted: true, videoMuted: true});
|
|
2670
2801
|
|
|
2802
|
+
// simulate OK being sent in response to remote answer being received
|
|
2803
|
+
await simulateRoapOk();
|
|
2804
|
+
|
|
2805
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
2806
|
+
checkOkSent({audioMuted: true, videoMuted: true});
|
|
2807
|
+
|
|
2671
2808
|
// and no other local mute requests were sent to Locus
|
|
2672
|
-
assert.
|
|
2809
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
2673
2810
|
});
|
|
2674
2811
|
|
|
2675
2812
|
it('updateMedia() disables media when stream is published', async () => {
|
|
@@ -2691,8 +2828,14 @@ describe('plugin-meetings', () => {
|
|
|
2691
2828
|
// check SDP offer was sent with the right audioMuted/videoMuted values
|
|
2692
2829
|
checkSdpOfferSent({audioMuted: true, videoMuted: true});
|
|
2693
2830
|
|
|
2831
|
+
// simulate OK being sent in response to remote answer being received
|
|
2832
|
+
await simulateRoapOk();
|
|
2833
|
+
|
|
2834
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
2835
|
+
checkOkSent({audioMuted: true, videoMuted: true});
|
|
2836
|
+
|
|
2694
2837
|
// and no other local mute requests were sent to Locus
|
|
2695
|
-
assert.
|
|
2838
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
2696
2839
|
});
|
|
2697
2840
|
|
|
2698
2841
|
it('updateMedia() enables media when stream is published', async () => {
|
|
@@ -2714,8 +2857,14 @@ describe('plugin-meetings', () => {
|
|
|
2714
2857
|
// check SDP offer was sent with the right audioMuted/videoMuted values
|
|
2715
2858
|
checkSdpOfferSent({audioMuted: false, videoMuted: true});
|
|
2716
2859
|
|
|
2860
|
+
// simulate OK being sent in response to remote answer being received
|
|
2861
|
+
await simulateRoapOk();
|
|
2862
|
+
|
|
2863
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
2864
|
+
checkOkSent({audioMuted: false, videoMuted: true});
|
|
2865
|
+
|
|
2717
2866
|
// and no other local mute requests were sent to Locus
|
|
2718
|
-
assert.
|
|
2867
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
2719
2868
|
});
|
|
2720
2869
|
});
|
|
2721
2870
|
|
|
@@ -2743,14 +2892,17 @@ describe('plugin-meetings', () => {
|
|
|
2743
2892
|
assert.notCalled(locusMediaRequestStub);
|
|
2744
2893
|
assert.notCalled(fakeRoapMediaConnection.update);
|
|
2745
2894
|
|
|
2746
|
-
// now simulate roap offer
|
|
2895
|
+
// now simulate roap offer and ok
|
|
2747
2896
|
await simulateRoapOffer();
|
|
2897
|
+
await simulateRoapOk();
|
|
2748
2898
|
|
|
2749
2899
|
// it should be sent with the right mute status
|
|
2750
2900
|
checkSdpOfferSent({audioMuted: mute, videoMuted: true});
|
|
2901
|
+
// check OK was sent with the right audioMuted/videoMuted values
|
|
2902
|
+
checkOkSent({audioMuted: mute, videoMuted: true});
|
|
2751
2903
|
|
|
2752
2904
|
// nothing else should happen
|
|
2753
|
-
assert.
|
|
2905
|
+
assert.calledTwice(locusMediaRequestStub);
|
|
2754
2906
|
assert.notCalled(fakeRoapMediaConnection.update);
|
|
2755
2907
|
})
|
|
2756
2908
|
);
|
|
@@ -5345,6 +5497,13 @@ describe('plugin-meetings', () => {
|
|
|
5345
5497
|
});
|
|
5346
5498
|
|
|
5347
5499
|
it('handles OK message correctly', () => {
|
|
5500
|
+
const clock = sinon.useFakeTimers();
|
|
5501
|
+
sinon.spy(clock, "clearTimeout");
|
|
5502
|
+
meeting.deferSDPAnswer = {
|
|
5503
|
+
resolve: sinon.stub(),
|
|
5504
|
+
};
|
|
5505
|
+
meeting.sdpResponseTimer = '1234';
|
|
5506
|
+
|
|
5348
5507
|
eventListeners[Event.ROAP_MESSAGE_TO_SEND]({
|
|
5349
5508
|
roapMessage: {messageType: 'OK', seq: 1},
|
|
5350
5509
|
});
|
|
@@ -5372,9 +5531,16 @@ describe('plugin-meetings', () => {
|
|
|
5372
5531
|
latency: undefined,
|
|
5373
5532
|
}
|
|
5374
5533
|
);
|
|
5534
|
+
|
|
5535
|
+
assert.calledOnce(meeting.deferSDPAnswer.resolve)
|
|
5536
|
+
assert.calledOnce(clock.clearTimeout)
|
|
5537
|
+
assert.calledWith(clock.clearTimeout, '1234')
|
|
5538
|
+
assert.equal(meeting.sdpResponseTimer, undefined)
|
|
5375
5539
|
});
|
|
5376
5540
|
|
|
5377
5541
|
it('handles OFFER message correctly', () => {
|
|
5542
|
+
assert.equal(meeting.deferSDPAnswer, undefined);
|
|
5543
|
+
|
|
5378
5544
|
eventListeners[Event.ROAP_MESSAGE_TO_SEND]({
|
|
5379
5545
|
roapMessage: {
|
|
5380
5546
|
messageType: 'OFFER',
|
|
@@ -5398,6 +5564,8 @@ describe('plugin-meetings', () => {
|
|
|
5398
5564
|
meeting,
|
|
5399
5565
|
reconnect: false,
|
|
5400
5566
|
});
|
|
5567
|
+
|
|
5568
|
+
assert.notEqual(meeting.deferSDPAnswer, undefined);
|
|
5401
5569
|
});
|
|
5402
5570
|
|
|
5403
5571
|
it('handles ANSWER message correctly', () => {
|
|
@@ -6351,6 +6519,18 @@ describe('plugin-meetings', () => {
|
|
|
6351
6519
|
meeting.webex.internal.mercury.off = sinon.stub().returns(true);
|
|
6352
6520
|
meeting.unsetPeerConnections();
|
|
6353
6521
|
assert.calledOnce(meeting.mediaProperties.unsetPeerConnection);
|
|
6522
|
+
assert.notCalled(meeting.webex.internal.mercury.off);
|
|
6523
|
+
});
|
|
6524
|
+
|
|
6525
|
+
it('should unset the peer connections and turn off mercury listeners if config.reconnection.detection is true', () => {
|
|
6526
|
+
meeting.config.reconnection.detection = true;
|
|
6527
|
+
meeting.mediaProperties.unsetPeerConnection = sinon.stub().returns(true);
|
|
6528
|
+
meeting.webex.internal.mercury.off = sinon.stub().returns(true);
|
|
6529
|
+
meeting.unsetPeerConnections();
|
|
6530
|
+
assert.calledOnce(meeting.mediaProperties.unsetPeerConnection);
|
|
6531
|
+
assert.calledTwice(meeting.webex.internal.mercury.off);
|
|
6532
|
+
assert.calledWith(meeting.webex.internal.mercury.off.firstCall, ONLINE);
|
|
6533
|
+
assert.calledWith(meeting.webex.internal.mercury.off.secondCall, OFFLINE);
|
|
6354
6534
|
});
|
|
6355
6535
|
});
|
|
6356
6536
|
|