@webex/plugin-meetings 3.8.1-next.3 → 3.8.1-next.31
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/README.md +26 -13
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/constants.js +21 -2
- 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/index.js +38 -84
- package/dist/locus-info/index.js.map +1 -1
- package/dist/media/index.js +2 -2
- package/dist/media/index.js.map +1 -1
- package/dist/meeting/brbState.js +14 -12
- package/dist/meeting/brbState.js.map +1 -1
- package/dist/meeting/index.js +169 -66
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +19 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meetings/index.js +35 -33
- package/dist/meetings/index.js.map +1 -1
- package/dist/members/index.js +8 -6
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +3 -3
- package/dist/members/request.js.map +1 -1
- package/dist/members/util.js +18 -6
- package/dist/members/util.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +1 -1
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +34 -5
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +42 -2
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +32 -2
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/reachability/index.js +5 -10
- package/dist/reachability/index.js.map +1 -1
- package/dist/types/constants.d.ts +19 -0
- package/dist/types/locus-info/index.d.ts +0 -9
- package/dist/types/meeting/brbState.d.ts +0 -1
- package/dist/types/meeting/index.d.ts +28 -4
- package/dist/types/meeting/request.d.ts +9 -1
- package/dist/types/meeting/request.type.d.ts +74 -0
- package/dist/types/members/index.d.ts +8 -3
- package/dist/types/members/request.d.ts +1 -1
- package/dist/types/members/util.d.ts +5 -2
- package/dist/types/multistream/remoteMedia.d.ts +20 -1
- package/dist/types/multistream/remoteMediaGroup.d.ts +11 -0
- package/dist/types/multistream/sendSlotManager.d.ts +16 -0
- package/dist/types/reachability/index.d.ts +2 -2
- package/dist/webinar/index.js +1 -1
- package/package.json +24 -24
- package/src/constants.ts +20 -0
- package/src/locus-info/index.ts +47 -82
- package/src/media/index.ts +2 -2
- package/src/meeting/brbState.ts +9 -7
- package/src/meeting/index.ts +126 -23
- package/src/meeting/request.ts +16 -0
- package/src/meeting/request.type.ts +64 -0
- package/src/meetings/index.ts +3 -2
- package/src/members/index.ts +7 -5
- package/src/members/request.ts +2 -2
- package/src/members/util.ts +14 -3
- package/src/multistream/mediaRequestManager.ts +7 -7
- package/src/multistream/remoteMedia.ts +34 -4
- package/src/multistream/remoteMediaGroup.ts +37 -2
- package/src/multistream/sendSlotManager.ts +34 -2
- package/src/reachability/index.ts +5 -13
- package/test/unit/spec/locus-info/index.js +177 -83
- package/test/unit/spec/media/index.ts +107 -0
- package/test/unit/spec/meeting/brbState.ts +9 -9
- package/test/unit/spec/meeting/index.js +606 -55
- package/test/unit/spec/meeting/request.js +71 -0
- package/test/unit/spec/meetings/index.js +1 -0
- package/test/unit/spec/members/index.js +32 -9
- package/test/unit/spec/members/request.js +2 -2
- package/test/unit/spec/members/utils.js +27 -7
- package/test/unit/spec/multistream/mediaRequestManager.ts +19 -6
- package/test/unit/spec/multistream/remoteMedia.ts +66 -2
- package/test/unit/spec/multistream/sendSlotManager.ts +59 -0
- package/test/unit/spec/reachability/index.ts +2 -6
@@ -305,7 +305,7 @@ describe('plugin-meetings', () => {
|
|
305
305
|
{state: newControls.rdcControl}
|
306
306
|
);
|
307
307
|
});
|
308
|
-
|
308
|
+
|
309
309
|
it('should trigger the CONTROLS_POLLING_QA_CHANGED event when necessary', () => {
|
310
310
|
locusInfo.controls = {};
|
311
311
|
locusInfo.emitScoped = sinon.stub();
|
@@ -834,39 +834,6 @@ describe('plugin-meetings', () => {
|
|
834
834
|
);
|
835
835
|
});
|
836
836
|
|
837
|
-
it('should update the deltaParticipants object', () => {
|
838
|
-
const prev = locusInfo.deltaParticipants;
|
839
|
-
|
840
|
-
locusInfo.updateParticipantDeltas(newParticipants);
|
841
|
-
|
842
|
-
assert.notEqual(locusInfo.deltaParticipants, prev);
|
843
|
-
});
|
844
|
-
|
845
|
-
it('should update the delta property on all changed states', () => {
|
846
|
-
locusInfo.updateParticipantDeltas(newParticipants);
|
847
|
-
|
848
|
-
const [exampleParticipant] = locusInfo.deltaParticipants;
|
849
|
-
|
850
|
-
assert.isTrue(exampleParticipant.delta.audioStatus);
|
851
|
-
assert.isTrue(exampleParticipant.delta.videoSlidesStatus);
|
852
|
-
assert.isTrue(exampleParticipant.delta.videoStatus);
|
853
|
-
});
|
854
|
-
|
855
|
-
it('should include the person details of the changed participant', () => {
|
856
|
-
locusInfo.updateParticipantDeltas(newParticipants);
|
857
|
-
|
858
|
-
const [exampleParticipant] = locusInfo.deltaParticipants;
|
859
|
-
|
860
|
-
assert.equal(exampleParticipant.person, newParticipants[0].person);
|
861
|
-
});
|
862
|
-
|
863
|
-
it('should clear deltaParticipants when no changes occured', () => {
|
864
|
-
locusInfo.participants = [...newParticipants];
|
865
|
-
|
866
|
-
locusInfo.updateParticipantDeltas(locusInfo.participants);
|
867
|
-
|
868
|
-
assert.isTrue(locusInfo.deltaParticipants.length === 0);
|
869
|
-
});
|
870
837
|
|
871
838
|
it('should call with participant display name', () => {
|
872
839
|
const failureParticipant = [
|
@@ -2108,6 +2075,38 @@ describe('plugin-meetings', () => {
|
|
2108
2075
|
assert.isFunction(locusParser.onDeltaAction);
|
2109
2076
|
});
|
2110
2077
|
|
2078
|
+
it("#updateLocusInfo invokes updateLocusUrl before updateMeetingInfo", () => {
|
2079
|
+
const callOrder = [];
|
2080
|
+
sinon.stub(locusInfo, "updateControls");
|
2081
|
+
sinon.stub(locusInfo, "updateConversationUrl");
|
2082
|
+
sinon.stub(locusInfo, "updateCreated");
|
2083
|
+
sinon.stub(locusInfo, "updateFullState");
|
2084
|
+
sinon.stub(locusInfo, "updateHostInfo");
|
2085
|
+
sinon.stub(locusInfo, "updateMeetingInfo").callsFake(() => {
|
2086
|
+
callOrder.push("updateMeetingInfo");
|
2087
|
+
});
|
2088
|
+
sinon.stub(locusInfo, "updateMediaShares");
|
2089
|
+
sinon.stub(locusInfo, "updateParticipantsUrl");
|
2090
|
+
sinon.stub(locusInfo, "updateReplace");
|
2091
|
+
sinon.stub(locusInfo, "updateSelf");
|
2092
|
+
sinon.stub(locusInfo, "updateLocusUrl").callsFake(() => {
|
2093
|
+
callOrder.push("updateLocusUrl");
|
2094
|
+
});
|
2095
|
+
sinon.stub(locusInfo, "updateAclUrl");
|
2096
|
+
sinon.stub(locusInfo, "updateBasequence");
|
2097
|
+
sinon.stub(locusInfo, "updateSequence");
|
2098
|
+
sinon.stub(locusInfo, "updateMemberShip");
|
2099
|
+
sinon.stub(locusInfo, "updateIdentifiers");
|
2100
|
+
sinon.stub(locusInfo, "updateEmbeddedApps");
|
2101
|
+
sinon.stub(locusInfo, "updateResources");
|
2102
|
+
sinon.stub(locusInfo, "compareAndUpdate");
|
2103
|
+
|
2104
|
+
locusInfo.updateLocusInfo(locus);
|
2105
|
+
|
2106
|
+
// Ensure updateLocusUrl is called before updateMeetingInfo if both are called
|
2107
|
+
assert.deepEqual(callOrder, ['updateLocusUrl', 'updateMeetingInfo']);
|
2108
|
+
});
|
2109
|
+
|
2111
2110
|
it('#updateLocusInfo ignores breakout LEFT message', () => {
|
2112
2111
|
const newLocus = {
|
2113
2112
|
self: {
|
@@ -2159,10 +2158,11 @@ describe('plugin-meetings', () => {
|
|
2159
2158
|
assert.notCalled(locusInfo.compareAndUpdate);
|
2160
2159
|
});
|
2161
2160
|
|
2161
|
+
|
2162
|
+
|
2162
2163
|
it('onFullLocus() updates the working-copy of locus parser', () => {
|
2163
2164
|
const eventType = 'fakeEvent';
|
2164
2165
|
|
2165
|
-
sandbox.stub(locusInfo, 'updateParticipantDeltas');
|
2166
2166
|
sandbox.stub(locusInfo, 'updateLocusInfo');
|
2167
2167
|
sandbox.stub(locusInfo, 'updateParticipants');
|
2168
2168
|
sandbox.stub(locusInfo, 'isMeetingActive');
|
@@ -2182,7 +2182,6 @@ describe('plugin-meetings', () => {
|
|
2182
2182
|
const oldWorkingCopy = locusParser.workingCopy;
|
2183
2183
|
|
2184
2184
|
const spies = [
|
2185
|
-
sandbox.stub(locusInfo, 'updateParticipantDeltas'),
|
2186
2185
|
sandbox.stub(locusInfo, 'updateLocusInfo'),
|
2187
2186
|
sandbox.stub(locusInfo, 'updateParticipants'),
|
2188
2187
|
sandbox.stub(locusInfo, 'isMeetingActive'),
|
@@ -2257,7 +2256,7 @@ describe('plugin-meetings', () => {
|
|
2257
2256
|
|
2258
2257
|
it('applyLocusDeltaData gets delta locus on DESYNC action if we have a syncUrl', () => {
|
2259
2258
|
const {DESYNC} = LocusDeltaParser.loci;
|
2260
|
-
const fakeDeltaLocus = {id: 'fake delta locus'};
|
2259
|
+
const fakeDeltaLocus = {baseSequence: {}, id: 'fake delta locus'};
|
2261
2260
|
const meeting = {
|
2262
2261
|
meetingRequest: {
|
2263
2262
|
getLocusDTO: sandbox.stub().resolves({body: fakeDeltaLocus}),
|
@@ -2392,25 +2391,22 @@ describe('plugin-meetings', () => {
|
|
2392
2391
|
};
|
2393
2392
|
});
|
2394
2393
|
|
2395
|
-
it('applyLocusDeltaData gets full locus on DESYNC action if we do not have a syncUrl and destroys the meeting if that fails', () => {
|
2394
|
+
it('applyLocusDeltaData gets full locus on DESYNC action if we do not have a syncUrl and destroys the meeting if that fails', async () => {
|
2396
2395
|
meeting.meetingRequest.getLocusDTO.rejects(new Error('fake error'));
|
2397
2396
|
|
2398
2397
|
locusInfo.locusParser.workingCopy = {}; // no syncUrl
|
2399
2398
|
|
2400
|
-
|
2401
|
-
// we will wait and stub it's last function to resolve this waiting promise.
|
2402
|
-
return new Promise((resolve) => {
|
2403
|
-
webex.meetings.destroy.callsFake(() => resolve());
|
2404
|
-
locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
|
2405
|
-
}).then(() => {
|
2406
|
-
assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {url: 'fullSyncUrl'});
|
2399
|
+
locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
|
2407
2400
|
|
2408
|
-
|
2409
|
-
assert.notCalled(meeting.locusInfo.onFullLocus);
|
2410
|
-
assert.notCalled(locusInfo.locusParser.resume);
|
2401
|
+
await testUtils.flushPromises();
|
2411
2402
|
|
2412
|
-
|
2413
|
-
|
2403
|
+
assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {url: 'fullSyncUrl'});
|
2404
|
+
|
2405
|
+
assert.notCalled(meeting.locusInfo.handleLocusDelta);
|
2406
|
+
assert.notCalled(meeting.locusInfo.onFullLocus);
|
2407
|
+
assert.notCalled(locusInfo.locusParser.resume);
|
2408
|
+
|
2409
|
+
assert.calledOnceWithExactly(webex.meetings.destroy, meeting, 'LOCUS_DTO_SYNC_FAILED');
|
2414
2410
|
});
|
2415
2411
|
|
2416
2412
|
it('applyLocusDeltaData first tries a delta sync on DESYNC action and if that fails, does a full locus sync', () => {
|
@@ -2447,39 +2443,62 @@ describe('plugin-meetings', () => {
|
|
2447
2443
|
});
|
2448
2444
|
});
|
2449
2445
|
|
2450
|
-
it('applyLocusDeltaData
|
2446
|
+
it('applyLocusDeltaData first tries a delta sync on DESYNC action and if that fails with 403, it does not do a full locus sync', async () => {
|
2447
|
+
const fake403Error = new Error('fake error');
|
2448
|
+
fake403Error.statusCode = 403;
|
2449
|
+
|
2450
|
+
meeting.meetingRequest.getLocusDTO.onCall(0).rejects(fake403Error);
|
2451
|
+
|
2452
|
+
locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
|
2453
|
+
|
2454
|
+
await testUtils.flushPromises();
|
2455
|
+
|
2456
|
+
assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {url: 'deltaSyncUrl'});
|
2457
|
+
|
2458
|
+
assert.calledWith(sendBehavioralMetricStub, 'js_sdk_locus_delta_sync_failed', {
|
2459
|
+
correlationId: meeting.correlationId,
|
2460
|
+
url: 'deltaSyncUrl',
|
2461
|
+
reason: 'fake error',
|
2462
|
+
errorName: 'Error',
|
2463
|
+
stack: sinon.match.any,
|
2464
|
+
code: sinon.match.any,
|
2465
|
+
});
|
2466
|
+
|
2467
|
+
assert.notCalled(meeting.locusInfo.handleLocusDelta);
|
2468
|
+
assert.notCalled(meeting.locusInfo.onFullLocus);
|
2469
|
+
assert.notCalled(locusInfo.locusParser.resume);
|
2470
|
+
});
|
2471
|
+
|
2472
|
+
it('applyLocusDeltaData destroys the meeting if both delta sync and full sync fail', async () => {
|
2451
2473
|
meeting.meetingRequest.getLocusDTO.rejects(new Error('fake error'));
|
2452
2474
|
|
2453
|
-
|
2454
|
-
// we will wait and stub it's last function to resolve this waiting promise.
|
2455
|
-
return new Promise((resolve) => {
|
2456
|
-
webex.meetings.destroy.callsFake(() => resolve());
|
2457
|
-
locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
|
2458
|
-
}).then(() => {
|
2459
|
-
assert.calledTwice(meeting.meetingRequest.getLocusDTO);
|
2475
|
+
locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
|
2460
2476
|
|
2461
|
-
|
2462
|
-
{url: 'deltaSyncUrl'},
|
2463
|
-
]);
|
2464
|
-
assert.deepEqual(meeting.meetingRequest.getLocusDTO.getCalls()[1].args, [
|
2465
|
-
{url: 'fullSyncUrl'},
|
2466
|
-
]);
|
2477
|
+
await testUtils.flushPromises();
|
2467
2478
|
|
2468
|
-
|
2469
|
-
correlationId: meeting.correlationId,
|
2470
|
-
url: 'deltaSyncUrl',
|
2471
|
-
reason: 'fake error',
|
2472
|
-
errorName: 'Error',
|
2473
|
-
stack: sinon.match.any,
|
2474
|
-
code: sinon.match.any,
|
2475
|
-
});
|
2479
|
+
assert.calledTwice(meeting.meetingRequest.getLocusDTO);
|
2476
2480
|
|
2477
|
-
|
2478
|
-
|
2479
|
-
|
2481
|
+
assert.deepEqual(meeting.meetingRequest.getLocusDTO.getCalls()[0].args, [
|
2482
|
+
{url: 'deltaSyncUrl'},
|
2483
|
+
]);
|
2484
|
+
assert.deepEqual(meeting.meetingRequest.getLocusDTO.getCalls()[1].args, [
|
2485
|
+
{url: 'fullSyncUrl'},
|
2486
|
+
]);
|
2480
2487
|
|
2481
|
-
|
2488
|
+
assert.calledWith(sendBehavioralMetricStub, 'js_sdk_locus_delta_sync_failed', {
|
2489
|
+
correlationId: meeting.correlationId,
|
2490
|
+
url: 'deltaSyncUrl',
|
2491
|
+
reason: 'fake error',
|
2492
|
+
errorName: 'Error',
|
2493
|
+
stack: sinon.match.any,
|
2494
|
+
code: sinon.match.any,
|
2482
2495
|
});
|
2496
|
+
|
2497
|
+
assert.notCalled(meeting.locusInfo.handleLocusDelta);
|
2498
|
+
assert.notCalled(meeting.locusInfo.onFullLocus);
|
2499
|
+
assert.notCalled(locusInfo.locusParser.resume);
|
2500
|
+
|
2501
|
+
assert.calledOnceWithExactly(webex.meetings.destroy, meeting, 'LOCUS_DTO_SYNC_FAILED');
|
2483
2502
|
});
|
2484
2503
|
});
|
2485
2504
|
|
@@ -2509,9 +2528,7 @@ describe('plugin-meetings', () => {
|
|
2509
2528
|
});
|
2510
2529
|
|
2511
2530
|
it('onDeltaLocus merges delta participants with existing participants', () => {
|
2512
|
-
const FAKE_DELTA_PARTICIPANTS = [
|
2513
|
-
{id: '1111'}, {id: '2222'}
|
2514
|
-
]
|
2531
|
+
const FAKE_DELTA_PARTICIPANTS = [{id: '1111'}, {id: '2222'}];
|
2515
2532
|
fakeLocus.participants = FAKE_DELTA_PARTICIPANTS;
|
2516
2533
|
|
2517
2534
|
sinon.spy(locusInfo, 'mergeParticipants');
|
@@ -2519,9 +2536,87 @@ describe('plugin-meetings', () => {
|
|
2519
2536
|
const existingParticipants = locusInfo.participants;
|
2520
2537
|
|
2521
2538
|
locusInfo.onDeltaLocus(fakeLocus);
|
2522
|
-
assert.calledOnceWithExactly(
|
2539
|
+
assert.calledOnceWithExactly(
|
2540
|
+
locusInfo.mergeParticipants,
|
2541
|
+
existingParticipants,
|
2542
|
+
FAKE_DELTA_PARTICIPANTS
|
2543
|
+
);
|
2523
2544
|
assert.calledWith(locusInfo.updateParticipants, FAKE_DELTA_PARTICIPANTS, false);
|
2524
2545
|
});
|
2546
|
+
|
2547
|
+
[true, false].forEach((isDelta) =>
|
2548
|
+
it(`applyLocusDeltaData - handles empty ${
|
2549
|
+
isDelta ? 'delta' : 'full'
|
2550
|
+
} DTO in response`, async () => {
|
2551
|
+
const {DESYNC} = LocusDeltaParser.loci;
|
2552
|
+
const fakeFullLocusDto = {};
|
2553
|
+
const meeting = {
|
2554
|
+
meetingRequest: {
|
2555
|
+
getLocusDTO: sandbox.stub().resolves({body: fakeFullLocusDto}),
|
2556
|
+
},
|
2557
|
+
locusInfo: {
|
2558
|
+
onFullLocus: sandbox.stub(),
|
2559
|
+
handleLocusDelta: sandbox.stub(),
|
2560
|
+
},
|
2561
|
+
locusUrl: 'fake locus FULL url',
|
2562
|
+
};
|
2563
|
+
|
2564
|
+
sinon.stub(locusInfo.locusParser, 'resume').resolves();
|
2565
|
+
|
2566
|
+
if (isDelta) {
|
2567
|
+
locusInfo.locusParser.workingCopy = {syncUrl: 'fake locus DELTA url'};
|
2568
|
+
} else {
|
2569
|
+
locusInfo.locusParser.workingCopy = {}; // no syncUrl (to trigger FULL DTO request)
|
2570
|
+
}
|
2571
|
+
|
2572
|
+
await locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
|
2573
|
+
|
2574
|
+
await testUtils.flushPromises();
|
2575
|
+
|
2576
|
+
if (isDelta) {
|
2577
|
+
assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {
|
2578
|
+
url: 'fake locus DELTA url',
|
2579
|
+
});
|
2580
|
+
} else {
|
2581
|
+
assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {
|
2582
|
+
url: 'fake locus FULL url',
|
2583
|
+
});
|
2584
|
+
}
|
2585
|
+
assert.notCalled(meeting.locusInfo.handleLocusDelta);
|
2586
|
+
assert.notCalled(meeting.locusInfo.onFullLocus);
|
2587
|
+
assert.calledOnce(locusInfo.locusParser.resume);
|
2588
|
+
})
|
2589
|
+
);
|
2590
|
+
|
2591
|
+
it(`applyLocusDeltaData - handles the case when we get FULL DTO when we asked for DELTA DTO`, async () => {
|
2592
|
+
const {DESYNC} = LocusDeltaParser.loci;
|
2593
|
+
const fakeFullLocusDto = {someStuff: 'data'}; // non-empty DTO, without baseSequence
|
2594
|
+
const meeting = {
|
2595
|
+
meetingRequest: {
|
2596
|
+
getLocusDTO: sandbox.stub().resolves({body: fakeFullLocusDto}),
|
2597
|
+
},
|
2598
|
+
locusInfo: {
|
2599
|
+
onFullLocus: sandbox.stub(),
|
2600
|
+
handleLocusDelta: sandbox.stub(),
|
2601
|
+
},
|
2602
|
+
locusUrl: 'fake locus FULL url',
|
2603
|
+
};
|
2604
|
+
|
2605
|
+
sinon.stub(locusInfo.locusParser, 'resume').resolves();
|
2606
|
+
|
2607
|
+
locusInfo.locusParser.workingCopy = {syncUrl: 'fake locus DELTA url'};
|
2608
|
+
|
2609
|
+
await locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
|
2610
|
+
|
2611
|
+
await testUtils.flushPromises();
|
2612
|
+
|
2613
|
+
assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {
|
2614
|
+
url: 'fake locus DELTA url',
|
2615
|
+
});
|
2616
|
+
assert.notCalled(meeting.locusInfo.handleLocusDelta);
|
2617
|
+
assert.calledOnceWithExactly(meeting.locusInfo.onFullLocus, fakeFullLocusDto);
|
2618
|
+
assert.calledOnce(locusInfo.locusParser.resume);
|
2619
|
+
});
|
2525
2620
|
});
|
2526
2621
|
|
2527
2622
|
describe('#updateLocusCache', () => {
|
@@ -2934,10 +3029,9 @@ describe('plugin-meetings', () => {
|
|
2934
3029
|
beforeEach(() => {
|
2935
3030
|
clock = sinon.useFakeTimers();
|
2936
3031
|
|
2937
|
-
sinon.stub(locusInfo, 'updateParticipantDeltas');
|
2938
3032
|
sinon.stub(locusInfo, 'updateParticipants');
|
2939
|
-
sinon.stub(locusInfo, 'isMeetingActive')
|
2940
|
-
sinon.stub(locusInfo, 'handleOneOnOneEvent')
|
3033
|
+
sinon.stub(locusInfo, 'isMeetingActive');
|
3034
|
+
sinon.stub(locusInfo, 'handleOneOnOneEvent');
|
2941
3035
|
(updateLocusInfoStub = sinon.stub(locusInfo, 'updateLocusInfo'));
|
2942
3036
|
syncRequestStub = sinon.stub().resolves({body: {}});
|
2943
3037
|
|
@@ -137,6 +137,113 @@ describe('createMediaConnection', () => {
|
|
137
137
|
);
|
138
138
|
});
|
139
139
|
|
140
|
+
it('should set direction to sendonly for both audio and video when only send flags are true', () => {
|
141
|
+
const roapMediaConnectionConstructorStub = sinon
|
142
|
+
.stub(InternalMediaCoreModule, 'RoapMediaConnection')
|
143
|
+
.returns(fakeRoapMediaConnection);
|
144
|
+
|
145
|
+
StaticConfig.set({bandwidth: {audio: 123, video: 456, startBitrate: 999}});
|
146
|
+
|
147
|
+
const ENABLE_EXTMAP = false;
|
148
|
+
const ENABLE_RTX = true;
|
149
|
+
|
150
|
+
Media.createMediaConnection(false, 'sendonly-debug-id', 'meetingId', {
|
151
|
+
mediaProperties: {
|
152
|
+
mediaDirection: {
|
153
|
+
sendAudio: true,
|
154
|
+
receiveAudio: false,
|
155
|
+
sendVideo: true,
|
156
|
+
receiveVideo: false,
|
157
|
+
sendShare: false,
|
158
|
+
receiveShare: false,
|
159
|
+
},
|
160
|
+
audioStream: fakeAudioStream,
|
161
|
+
videoStream: fakeVideoStream,
|
162
|
+
shareVideoTrack: null,
|
163
|
+
shareAudioTrack: null,
|
164
|
+
},
|
165
|
+
remoteQualityLevel: 'HIGH',
|
166
|
+
enableRtx: ENABLE_RTX,
|
167
|
+
enableExtmap: ENABLE_EXTMAP,
|
168
|
+
turnServerInfo: undefined,
|
169
|
+
iceCandidatesTimeout: undefined,
|
170
|
+
});
|
171
|
+
|
172
|
+
assert.calledWith(
|
173
|
+
roapMediaConnectionConstructorStub,
|
174
|
+
sinon.match.any,
|
175
|
+
{
|
176
|
+
localTracks: {
|
177
|
+
audio: fakeTrack,
|
178
|
+
video: fakeTrack,
|
179
|
+
screenShareVideo: undefined,
|
180
|
+
screenShareAudio: undefined,
|
181
|
+
},
|
182
|
+
direction: {
|
183
|
+
audio: 'sendonly',
|
184
|
+
video: 'sendonly',
|
185
|
+
screenShareVideo: 'inactive',
|
186
|
+
},
|
187
|
+
remoteQualityLevel: 'HIGH',
|
188
|
+
},
|
189
|
+
'sendonly-debug-id'
|
190
|
+
);
|
191
|
+
});
|
192
|
+
|
193
|
+
it('should set direction to recvonly for both audio and video when only receive flags are true', () => {
|
194
|
+
const roapMediaConnectionConstructorStub = sinon
|
195
|
+
.stub(InternalMediaCoreModule, 'RoapMediaConnection')
|
196
|
+
.returns(fakeRoapMediaConnection);
|
197
|
+
|
198
|
+
StaticConfig.set({bandwidth: {audio: 123, video: 456, startBitrate: 999}});
|
199
|
+
|
200
|
+
const ENABLE_EXTMAP = true;
|
201
|
+
const ENABLE_RTX = false;
|
202
|
+
|
203
|
+
Media.createMediaConnection(false, 'recvonly-debug-id', 'meetingId', {
|
204
|
+
mediaProperties: {
|
205
|
+
mediaDirection: {
|
206
|
+
sendAudio: false,
|
207
|
+
receiveAudio: true,
|
208
|
+
sendVideo: false,
|
209
|
+
receiveVideo: true,
|
210
|
+
sendShare: false,
|
211
|
+
receiveShare: false,
|
212
|
+
},
|
213
|
+
audioStream: fakeAudioStream,
|
214
|
+
videoStream: fakeVideoStream,
|
215
|
+
shareVideoTrack: null,
|
216
|
+
shareAudioTrack: null,
|
217
|
+
},
|
218
|
+
remoteQualityLevel: 'HIGH',
|
219
|
+
enableRtx: ENABLE_RTX,
|
220
|
+
enableExtmap: ENABLE_EXTMAP,
|
221
|
+
turnServerInfo: undefined,
|
222
|
+
iceCandidatesTimeout: undefined,
|
223
|
+
});
|
224
|
+
|
225
|
+
assert.calledWith(
|
226
|
+
roapMediaConnectionConstructorStub,
|
227
|
+
sinon.match.any,
|
228
|
+
{
|
229
|
+
localTracks: {
|
230
|
+
audio: fakeTrack,
|
231
|
+
video: fakeTrack,
|
232
|
+
screenShareVideo: undefined,
|
233
|
+
screenShareAudio: undefined,
|
234
|
+
},
|
235
|
+
direction: {
|
236
|
+
audio: 'recvonly',
|
237
|
+
video: 'recvonly',
|
238
|
+
screenShareVideo: 'inactive',
|
239
|
+
},
|
240
|
+
remoteQualityLevel: 'HIGH',
|
241
|
+
},
|
242
|
+
'recvonly-debug-id'
|
243
|
+
);
|
244
|
+
});
|
245
|
+
|
246
|
+
|
140
247
|
it('creates a MultistreamRoapMediaConnection when multistream is enabled', () => {
|
141
248
|
const multistreamRoapMediaConnectionConstructorStub = sinon
|
142
249
|
.stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
|
@@ -3,12 +3,12 @@ import {assert, expect} from '@webex/test-helper-chai';
|
|
3
3
|
|
4
4
|
import testUtils from '../../../utils/testUtils';
|
5
5
|
import {BrbState, createBrbState} from '@webex/plugin-meetings/src/meeting/brbState';
|
6
|
-
import
|
6
|
+
import {MediaType} from '@webex/internal-media-core';
|
7
7
|
|
8
8
|
describe('plugin-meetings', () => {
|
9
9
|
let meeting: any;
|
10
10
|
let brbState: BrbState;
|
11
|
-
let setBrbStub: sinon.SinonStub;
|
11
|
+
let setBrbStub: sinon.SinonStub;
|
12
12
|
|
13
13
|
beforeEach(async () => {
|
14
14
|
meeting = {
|
@@ -23,7 +23,7 @@ describe('plugin-meetings', () => {
|
|
23
23
|
setSourceStateOverride: sinon.stub(),
|
24
24
|
},
|
25
25
|
meetingRequest: {
|
26
|
-
setBrb: () => {}
|
26
|
+
setBrb: () => {},
|
27
27
|
},
|
28
28
|
};
|
29
29
|
|
@@ -104,12 +104,12 @@ describe('plugin-meetings', () => {
|
|
104
104
|
assert.isTrue(meeting.meetingRequest.setBrb.calledOnce);
|
105
105
|
});
|
106
106
|
|
107
|
-
it('
|
107
|
+
it('updates source state override', async () => {
|
108
108
|
brbState.enable(true, meeting.sendSlotManager);
|
109
109
|
brbState.handleServerBrbUpdate(true);
|
110
110
|
await testUtils.flushPromises();
|
111
111
|
|
112
|
-
assert.isTrue(meeting.sendSlotManager.setSourceStateOverride.
|
112
|
+
assert.isTrue(meeting.sendSlotManager.setSourceStateOverride.called);
|
113
113
|
});
|
114
114
|
|
115
115
|
it('handles server update', async () => {
|
@@ -141,12 +141,12 @@ describe('plugin-meetings', () => {
|
|
141
141
|
it('should reject when sendLocalBrbStateToServer fails', async () => {
|
142
142
|
const error = new Error('send failed');
|
143
143
|
setBrbStub.rejects(error);
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
).to.be.rejectedWith(error);
|
144
|
+
|
145
|
+
const enablePromise = brbState.enable(true, meeting.sendSlotManager);
|
146
|
+
await expect(enablePromise).to.be.rejectedWith(error);
|
148
147
|
|
149
148
|
assert.isFalse(brbState.state.syncToServerInProgress);
|
149
|
+
expect(meeting.sendSlotManager.setSourceStateOverride.called).to.be.false;
|
150
150
|
});
|
151
151
|
});
|
152
152
|
});
|