@webex/plugin-meetings 3.9.0-webinar5k.1 → 3.9.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/constants.js +16 -0
- 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 +40 -328
- package/dist/locus-info/index.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 +196 -160
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/muteState.js +5 -2
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/type.js +7 -0
- package/dist/meeting/type.js.map +1 -0
- package/dist/meeting/util.js +79 -10
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +37 -39
- package/dist/meetings/index.js.map +1 -1
- package/dist/member/types.js.map +1 -1
- package/dist/members/collection.js +0 -13
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +21 -40
- package/dist/members/index.js.map +1 -1
- 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/types/constants.d.ts +16 -0
- package/dist/types/locus-info/index.d.ts +3 -102
- package/dist/types/meeting/in-meeting-actions.d.ts +6 -0
- package/dist/types/meeting/index.d.ts +23 -28
- package/dist/types/meeting/type.d.ts +9 -0
- package/dist/types/meeting/util.d.ts +6 -3
- package/dist/types/member/types.d.ts +0 -1
- package/dist/types/members/collection.d.ts +0 -6
- package/dist/types/members/index.d.ts +7 -16
- package/dist/types/members/util.d.ts +2 -1
- package/dist/types/multistream/remoteMedia.d.ts +20 -1
- package/dist/types/multistream/remoteMediaGroup.d.ts +11 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -24
- package/src/constants.ts +16 -2
- package/src/locus-info/index.ts +39 -409
- package/src/meeting/in-meeting-actions.ts +13 -0
- package/src/meeting/index.ts +92 -63
- package/src/meeting/muteState.ts +6 -2
- package/src/meeting/type.ts +9 -0
- package/src/meeting/util.ts +93 -19
- package/src/meetings/index.ts +6 -19
- package/src/member/types.ts +0 -1
- package/src/members/collection.ts +0 -11
- package/src/members/index.ts +10 -33
- package/src/members/util.ts +2 -1
- package/src/multistream/mediaRequestManager.ts +7 -7
- package/src/multistream/remoteMedia.ts +34 -4
- package/src/multistream/remoteMediaGroup.ts +37 -2
- package/test/unit/spec/locus-info/index.js +8 -365
- package/test/unit/spec/meeting/in-meeting-actions.ts +6 -0
- package/test/unit/spec/meeting/index.js +254 -38
- package/test/unit/spec/meeting/utils.js +122 -1
- package/test/unit/spec/meetings/index.js +2 -0
- package/test/unit/spec/members/index.js +37 -1
- package/test/unit/spec/multistream/mediaRequestManager.ts +19 -6
- package/test/unit/spec/multistream/remoteMedia.ts +66 -2
- package/dist/hashTree/constants.js +0 -23
- package/dist/hashTree/constants.js.map +0 -1
- package/dist/hashTree/hashTree.js +0 -516
- package/dist/hashTree/hashTree.js.map +0 -1
- package/dist/hashTree/hashTreeParser.js +0 -521
- package/dist/hashTree/hashTreeParser.js.map +0 -1
- package/dist/types/hashTree/constants.d.ts +0 -8
- package/dist/types/hashTree/hashTree.d.ts +0 -128
- package/dist/types/hashTree/hashTreeParser.d.ts +0 -152
- package/src/hashTree/constants.ts +0 -12
- package/src/hashTree/hashTree.ts +0 -460
- package/src/hashTree/hashTreeParser.ts +0 -556
- package/test/unit/spec/hashTree/hashTree.ts +0 -394
- package/test/unit/spec/hashTree/hashTreeParser.ts +0 -156
@@ -772,7 +772,7 @@ describe('plugin-meetings', () => {
|
|
772
772
|
},
|
773
773
|
};
|
774
774
|
locusInfo.emitScoped = sinon.stub();
|
775
|
-
locusInfo.updateParticipants({}
|
775
|
+
locusInfo.updateParticipants({});
|
776
776
|
|
777
777
|
// if this assertion fails, double-check the attributes used in
|
778
778
|
// the updateParticipants function in locus-info/index.js
|
@@ -790,7 +790,6 @@ describe('plugin-meetings', () => {
|
|
790
790
|
selfId: '2',
|
791
791
|
hostId: '3',
|
792
792
|
isReplace: undefined,
|
793
|
-
removedParticipantIds: [],
|
794
793
|
}
|
795
794
|
);
|
796
795
|
// note: in a real use case, recordingId, selfId, and hostId would all be the same
|
@@ -815,7 +814,7 @@ describe('plugin-meetings', () => {
|
|
815
814
|
};
|
816
815
|
|
817
816
|
locusInfo.emitScoped = sinon.stub();
|
818
|
-
locusInfo.updateParticipants({},
|
817
|
+
locusInfo.updateParticipants({}, true);
|
819
818
|
|
820
819
|
assert.calledWith(
|
821
820
|
locusInfo.emitScoped,
|
@@ -831,44 +830,10 @@ describe('plugin-meetings', () => {
|
|
831
830
|
selfId: '2',
|
832
831
|
hostId: '3',
|
833
832
|
isReplace: true,
|
834
|
-
removedParticipantIds: [],
|
835
833
|
}
|
836
834
|
);
|
837
835
|
});
|
838
836
|
|
839
|
-
it('should update the deltaParticipants object', () => {
|
840
|
-
const prev = locusInfo.deltaParticipants;
|
841
|
-
|
842
|
-
locusInfo.updateParticipantDeltas(newParticipants);
|
843
|
-
|
844
|
-
assert.notEqual(locusInfo.deltaParticipants, prev);
|
845
|
-
});
|
846
|
-
|
847
|
-
it('should update the delta property on all changed states', () => {
|
848
|
-
locusInfo.updateParticipantDeltas(newParticipants);
|
849
|
-
|
850
|
-
const [exampleParticipant] = locusInfo.deltaParticipants;
|
851
|
-
|
852
|
-
assert.isTrue(exampleParticipant.delta.audioStatus);
|
853
|
-
assert.isTrue(exampleParticipant.delta.videoSlidesStatus);
|
854
|
-
assert.isTrue(exampleParticipant.delta.videoStatus);
|
855
|
-
});
|
856
|
-
|
857
|
-
it('should include the person details of the changed participant', () => {
|
858
|
-
locusInfo.updateParticipantDeltas(newParticipants);
|
859
|
-
|
860
|
-
const [exampleParticipant] = locusInfo.deltaParticipants;
|
861
|
-
|
862
|
-
assert.equal(exampleParticipant.person, newParticipants[0].person);
|
863
|
-
});
|
864
|
-
|
865
|
-
it('should clear deltaParticipants when no changes occured', () => {
|
866
|
-
locusInfo.participants = [...newParticipants];
|
867
|
-
|
868
|
-
locusInfo.updateParticipantDeltas(locusInfo.participants);
|
869
|
-
|
870
|
-
assert.isTrue(locusInfo.deltaParticipants.length === 0);
|
871
|
-
});
|
872
837
|
|
873
838
|
it('should call with participant display name', () => {
|
874
839
|
const failureParticipant = [
|
@@ -882,7 +847,7 @@ describe('plugin-meetings', () => {
|
|
882
847
|
];
|
883
848
|
|
884
849
|
locusInfo.emitScoped = sinon.stub();
|
885
|
-
locusInfo.updateParticipants(failureParticipant
|
850
|
+
locusInfo.updateParticipants(failureParticipant);
|
886
851
|
assert.calledWith(
|
887
852
|
locusInfo.emitScoped,
|
888
853
|
{
|
@@ -2063,7 +2028,7 @@ describe('plugin-meetings', () => {
|
|
2063
2028
|
|
2064
2029
|
fakeLocus = {
|
2065
2030
|
meeting: true,
|
2066
|
-
participants:
|
2031
|
+
participants: true,
|
2067
2032
|
url: 'newLocusUrl',
|
2068
2033
|
syncUrl: 'newSyncUrl',
|
2069
2034
|
};
|
@@ -2198,7 +2163,6 @@ describe('plugin-meetings', () => {
|
|
2198
2163
|
it('onFullLocus() updates the working-copy of locus parser', () => {
|
2199
2164
|
const eventType = 'fakeEvent';
|
2200
2165
|
|
2201
|
-
sandbox.stub(locusInfo, 'updateParticipantDeltas');
|
2202
2166
|
sandbox.stub(locusInfo, 'updateLocusInfo');
|
2203
2167
|
sandbox.stub(locusInfo, 'updateParticipants');
|
2204
2168
|
sandbox.stub(locusInfo, 'isMeetingActive');
|
@@ -2218,7 +2182,6 @@ describe('plugin-meetings', () => {
|
|
2218
2182
|
const oldWorkingCopy = locusParser.workingCopy;
|
2219
2183
|
|
2220
2184
|
const spies = [
|
2221
|
-
sandbox.stub(locusInfo, 'updateParticipantDeltas'),
|
2222
2185
|
sandbox.stub(locusInfo, 'updateLocusInfo'),
|
2223
2186
|
sandbox.stub(locusInfo, 'updateParticipants'),
|
2224
2187
|
sandbox.stub(locusInfo, 'isMeetingActive'),
|
@@ -2540,7 +2503,7 @@ describe('plugin-meetings', () => {
|
|
2540
2503
|
});
|
2541
2504
|
|
2542
2505
|
it('onDeltaLocus handle delta data', () => {
|
2543
|
-
fakeLocus.participants =
|
2506
|
+
fakeLocus.participants = {};
|
2544
2507
|
const fakeBreakout = {
|
2545
2508
|
sessionId: 'sessionId',
|
2546
2509
|
groupId: 'groupId',
|
@@ -2557,11 +2520,11 @@ describe('plugin-meetings', () => {
|
|
2557
2520
|
};
|
2558
2521
|
locusInfo.updateParticipants = sinon.stub();
|
2559
2522
|
locusInfo.onDeltaLocus(fakeLocus);
|
2560
|
-
assert.calledWith(locusInfo.updateParticipants,
|
2523
|
+
assert.calledWith(locusInfo.updateParticipants, {}, false);
|
2561
2524
|
|
2562
2525
|
fakeLocus.controls.breakout.sessionId = 'sessionId2';
|
2563
2526
|
locusInfo.onDeltaLocus(fakeLocus);
|
2564
|
-
assert.calledWith(locusInfo.updateParticipants,
|
2527
|
+
assert.calledWith(locusInfo.updateParticipants, {}, true);
|
2565
2528
|
});
|
2566
2529
|
|
2567
2530
|
it('onDeltaLocus merges delta participants with existing participants', () => {
|
@@ -2578,7 +2541,7 @@ describe('plugin-meetings', () => {
|
|
2578
2541
|
existingParticipants,
|
2579
2542
|
FAKE_DELTA_PARTICIPANTS
|
2580
2543
|
);
|
2581
|
-
assert.calledWith(locusInfo.updateParticipants, FAKE_DELTA_PARTICIPANTS,
|
2544
|
+
assert.calledWith(locusInfo.updateParticipants, FAKE_DELTA_PARTICIPANTS, false);
|
2582
2545
|
});
|
2583
2546
|
|
2584
2547
|
[true, false].forEach((isDelta) =>
|
@@ -3066,7 +3029,6 @@ describe('plugin-meetings', () => {
|
|
3066
3029
|
beforeEach(() => {
|
3067
3030
|
clock = sinon.useFakeTimers();
|
3068
3031
|
|
3069
|
-
sinon.stub(locusInfo, 'updateParticipantDeltas');
|
3070
3032
|
sinon.stub(locusInfo, 'updateParticipants');
|
3071
3033
|
sinon.stub(locusInfo, 'isMeetingActive');
|
3072
3034
|
sinon.stub(locusInfo, 'handleOneOnOneEvent');
|
@@ -3090,7 +3052,6 @@ describe('plugin-meetings', () => {
|
|
3090
3052
|
id: 'test person id',
|
3091
3053
|
},
|
3092
3054
|
},
|
3093
|
-
participants: [],
|
3094
3055
|
});
|
3095
3056
|
|
3096
3057
|
updateLocusInfoStub.resetHistory();
|
@@ -3239,7 +3200,6 @@ describe('plugin-meetings', () => {
|
|
3239
3200
|
await testUtils.flushPromises();
|
3240
3201
|
|
3241
3202
|
assert.calledOnceWithExactly(syncRequestStub, {url: mockMeeting.locusUrl});
|
3242
|
-
assert.calledOnce(updateLocusInfoStub);
|
3243
3203
|
assert.calledOnceWithExactly(updateLocusInfoStub, fullLocus);
|
3244
3204
|
});
|
3245
3205
|
|
@@ -3315,322 +3275,5 @@ describe('plugin-meetings', () => {
|
|
3315
3275
|
assert.calledWith(updateLocusInfoStub.getCall(2), deltaEvents[7]);
|
3316
3276
|
});
|
3317
3277
|
});
|
3318
|
-
|
3319
|
-
describe('Hash trees - webinar 5k', () => {
|
3320
|
-
let mockFullLocus;
|
3321
|
-
let clock;
|
3322
|
-
|
3323
|
-
beforeEach(() => {
|
3324
|
-
|
3325
|
-
sinon.stub(Math, 'random').returns(0.5); // to make sure the backoff timer is predictable
|
3326
|
-
|
3327
|
-
mockFullLocus = {
|
3328
|
-
dataSets: [
|
3329
|
-
{
|
3330
|
-
url: 'https://locus-a.wbx2.com/locus/api/v1/loci/97d64a5f/session/a73e9f2c/datasets/main',
|
3331
|
-
root: '9bb9d5a911a74d53a915b4dfbec7329f',
|
3332
|
-
version: 51118,
|
3333
|
-
leafCount: 16,
|
3334
|
-
name: 'main',
|
3335
|
-
idleMs : 5000,
|
3336
|
-
backoff : {
|
3337
|
-
maxMs : 500,
|
3338
|
-
exponent : 0.5
|
3339
|
-
},
|
3340
|
-
},
|
3341
|
-
{
|
3342
|
-
url: 'https://locus-a.wbx2.com/locus/api/v1/loci/97d64a5f/session/a73e9f2c/participant/713e9f99/datasets/self',
|
3343
|
-
root: '5b8cc7ffda1346d2bfb1c0b60b8ab601',
|
3344
|
-
version: 89891,
|
3345
|
-
leafCount: 1,
|
3346
|
-
name: 'self',
|
3347
|
-
idleMs : 10000,
|
3348
|
-
backoff : {
|
3349
|
-
maxMs : 500,
|
3350
|
-
exponent : 0.5
|
3351
|
-
},
|
3352
|
-
},
|
3353
|
-
{
|
3354
|
-
url: 'https://locus-a.wbx2.com/locus/api/v1/loci/97d64a5f/session/a73e9f2c/datasets/atd-unmuted',
|
3355
|
-
root: '9279d2e149da43a1b8e2cd7cbf77f9f0',
|
3356
|
-
version: 91277,
|
3357
|
-
leafCount: 16,
|
3358
|
-
name: 'atd-unmuted',
|
3359
|
-
idleMs : 15000,
|
3360
|
-
backoff : {
|
3361
|
-
maxMs : 500,
|
3362
|
-
exponent : 0.5
|
3363
|
-
},
|
3364
|
-
},
|
3365
|
-
],
|
3366
|
-
locus: {
|
3367
|
-
url: 'https://locus-a.wbx2.com/locus/api/v1/loci/97d64a5f',
|
3368
|
-
htMeta: {
|
3369
|
-
elementId: {
|
3370
|
-
type: 'LOCUS',
|
3371
|
-
id: 0,
|
3372
|
-
version: 5678,
|
3373
|
-
},
|
3374
|
-
dataSetNames: ['main'],
|
3375
|
-
},
|
3376
|
-
participants: [
|
3377
|
-
{
|
3378
|
-
url: 'https://locus-a.wbx2.com/locus/api/v1/loci/97d64a5f/participant/11941033',
|
3379
|
-
person: {
|
3380
|
-
id: '111',
|
3381
|
-
name: '1st participant',
|
3382
|
-
},
|
3383
|
-
htMeta: {
|
3384
|
-
elementId: {
|
3385
|
-
type: 'PARTICIPANT',
|
3386
|
-
id: 2,
|
3387
|
-
version: 5678,
|
3388
|
-
},
|
3389
|
-
dataSetNames: ['atd-active', 'attendees', 'atd-unmuted'],
|
3390
|
-
},
|
3391
|
-
},
|
3392
|
-
{
|
3393
|
-
url: 'https://locus-a.wbx2.com/locus/api/v1/loci/97d64a5f/participant/11941034',
|
3394
|
-
person: {
|
3395
|
-
id: '222',
|
3396
|
-
name: '2nd participant',
|
3397
|
-
},
|
3398
|
-
htMeta: {
|
3399
|
-
elementId: {
|
3400
|
-
type: 'PARTICIPANT',
|
3401
|
-
id: 3,
|
3402
|
-
version: 5678,
|
3403
|
-
},
|
3404
|
-
dataSetNames: ['attendees'],
|
3405
|
-
},
|
3406
|
-
},
|
3407
|
-
],
|
3408
|
-
self: {
|
3409
|
-
url: 'https://locus-a.wbx2.com/locus/api/v1/loci/97d64a5f/participant/11941033',
|
3410
|
-
visibleDataSets: ['main', 'self', 'atd-unmuted'],
|
3411
|
-
person: {
|
3412
|
-
id: '333',
|
3413
|
-
name: 'myself',
|
3414
|
-
},
|
3415
|
-
htMeta: {
|
3416
|
-
elementId: {
|
3417
|
-
type: 'SELF',
|
3418
|
-
id: 4,
|
3419
|
-
version: 5678,
|
3420
|
-
},
|
3421
|
-
dataSetNames: ['self'],
|
3422
|
-
},
|
3423
|
-
},
|
3424
|
-
},
|
3425
|
-
};
|
3426
|
-
|
3427
|
-
clock = sinon.useFakeTimers();
|
3428
|
-
|
3429
|
-
});
|
3430
|
-
|
3431
|
-
afterEach(() => {
|
3432
|
-
clock.restore();
|
3433
|
-
});
|
3434
|
-
|
3435
|
-
const getMaxBackoffTime = (dataSets) => {
|
3436
|
-
return Object.values(dataSets).reduce((max, dataSet) => {
|
3437
|
-
const maxBackOff = dataSet.idleMs + dataSet.backoff.maxMs;
|
3438
|
-
return Math.max(max, maxBackOff);
|
3439
|
-
}, 0);
|
3440
|
-
}
|
3441
|
-
|
3442
|
-
const waitForMaxPossibleBackoffTime = async (dataSets) => {
|
3443
|
-
const maxBackoffTime = getMaxBackoffTime(dataSets);
|
3444
|
-
clock.tick(maxBackoffTime);
|
3445
|
-
await testUtils.flushPromises();
|
3446
|
-
}
|
3447
|
-
|
3448
|
-
it('initializes hash trees correctly from initial full locus', () => {
|
3449
|
-
locusInfo.initialSetup(mockFullLocus.locus, mockFullLocus.dataSets);
|
3450
|
-
|
3451
|
-
// check that the hash tree parser is initialized correctly
|
3452
|
-
assert.isDefined(locusInfo.hashTreeParser);
|
3453
|
-
assert.deepEqual(Object.keys(locusInfo.hashTreeParser.dataSets), ['main', 'self', 'atd-unmuted']);
|
3454
|
-
assert.deepEqual(locusInfo.hashTreeParser.dataSets['main'].hashTree.getLeafData(0), [ { type: 'LOCUS', id: 0, version: 5678 } ]);
|
3455
|
-
assert.deepEqual(locusInfo.hashTreeParser.dataSets['self'].hashTree.getLeafData(0), [ { type: 'SELF', id: 4, version: 5678 } ]);
|
3456
|
-
assert.deepEqual(locusInfo.hashTreeParser.dataSets['atd-unmuted'].hashTree.getLeafData(2), [ { type: 'PARTICIPANT', id: 2, version: 5678 } ]);
|
3457
|
-
|
3458
|
-
// participant with id=3 is not part of any of our datasets, so should be undefined
|
3459
|
-
assert.deepEqual(locusInfo.hashTreeParser.dataSets['atd-unmuted'].hashTree.getLeafData(3), []);
|
3460
|
-
});
|
3461
|
-
|
3462
|
-
it('handles hash tree messages correctly', async () => {
|
3463
|
-
locusInfo.initialSetup(mockFullLocus.locus, mockFullLocus.dataSets);
|
3464
|
-
|
3465
|
-
// simulate a hash tree message for a participant
|
3466
|
-
locusInfo.parse(mockMeeting, {
|
3467
|
-
"locusUrl" : "https://locus.wbx2.com/locus/api/v1/loci/dbe6eeb9-49c7-4727-bdb1-1c59fa6e56d2",
|
3468
|
-
"locusSessionId" : "fe3d019c-08ca-0f21-919f-f2cc646030ae",
|
3469
|
-
"dataSets" : [ {
|
3470
|
-
"url" : "https://locus.wbx2.com/locus/api/v1/loci/dbe6eeb9-49c7-4727-bdb1-1c59fa6e56d2/session/fe3d019c-08ca-0f21-919f-f2cc646030ae/datasets/attendees",
|
3471
|
-
"name" : "attendees",
|
3472
|
-
"root" : "7cfc14bdae7909e6fe7acd37bebf66db",
|
3473
|
-
"version" : 4739733700975,
|
3474
|
-
"leafCount" : 16,
|
3475
|
-
"idleMs" : 5000,
|
3476
|
-
"backoff" : {
|
3477
|
-
"maxMs" : 500,
|
3478
|
-
"exponent" : 0.5
|
3479
|
-
}
|
3480
|
-
}, {
|
3481
|
-
"url" : "https://locus.wbx2.com/locus/api/v1/loci/dbe6eeb9-49c7-4727-bdb1-1c59fa6e56d2/session/fe3d019c-08ca-0f21-919f-f2cc646030ae/datasets/atd-active",
|
3482
|
-
"name" : "atd-unmuted",
|
3483
|
-
"root" : "178bff6e3344f551a811712c57a9eac3",
|
3484
|
-
"version" : 5738696122316,
|
3485
|
-
"leafCount" : 4,
|
3486
|
-
"idleMs" : 5000,
|
3487
|
-
"backoff" : {
|
3488
|
-
"maxMs" : 500,
|
3489
|
-
"exponent" : 0.5
|
3490
|
-
}
|
3491
|
-
} ],
|
3492
|
-
"locusStateElements" : [ {
|
3493
|
-
"htMeta" : {
|
3494
|
-
"elementId" : {
|
3495
|
-
"type" : "PARTICIPANT",
|
3496
|
-
"id" : 2,
|
3497
|
-
"version" : 5679
|
3498
|
-
},
|
3499
|
-
"dataSetNames" : [ "attendees", "atd-unmuted" ]
|
3500
|
-
},
|
3501
|
-
"data" : "{\"isCreator\":false,\"url\":\"https://locus.wbx2.com/locus/api/v1/loci/dbe6eeb9-49c7-4727-bdb1-1c59fa6e56d2/participant/18ef210c-234a-49ac-83d6-1803bc401bc9\",\"id\":\"18ef210c-234a-49ac-83d6-1803bc401bc9\",\"guest\":false,\"resourceGuest\":false,\"moderator\":false,\"panelist\":false}"
|
3502
|
-
}, {
|
3503
|
-
"htMeta" : {
|
3504
|
-
"elementId" : {
|
3505
|
-
"type" : "PARTICIPANT",
|
3506
|
-
"id" : 3,
|
3507
|
-
"version" : 999999
|
3508
|
-
},
|
3509
|
-
"dataSetNames" : [ "attendees" ]
|
3510
|
-
},
|
3511
|
-
"data" : "{\"isCreator\":false,\"url\":\"https://locus.wbx2.com/locus/api/v1/loci/dbe6eeb9-49c7-4727-bdb1-1c59fa6e56d2/participant/29c0751a-7ada-40a1-94a4-eb5f5c80c863\",\"id\":\"29c0751a-7ada-40a1-94a4-eb5f5c80c863\",\"guest\":false,\"resourceGuest\":false,\"moderator\":false,\"panelist\":false}"
|
3512
|
-
} ]
|
3513
|
-
});
|
3514
|
-
|
3515
|
-
// main and self should be unchanged
|
3516
|
-
assert.deepEqual(Object.keys(locusInfo.hashTreeParser.dataSets), ['main', 'self', 'atd-unmuted']);
|
3517
|
-
assert.deepEqual(locusInfo.hashTreeParser.dataSets['main'].hashTree.getLeafData(0), [ { type: 'LOCUS', id: 0, version: 5678 } ]);
|
3518
|
-
assert.deepEqual(locusInfo.hashTreeParser.dataSets['self'].hashTree.getLeafData(0), [ { type: 'SELF', id: 4, version: 5678 } ]);
|
3519
|
-
|
3520
|
-
// participant should be updated
|
3521
|
-
assert.deepEqual(locusInfo.hashTreeParser.dataSets['atd-unmuted'].hashTree.getLeafData(2), [ { type: 'PARTICIPANT', id: 2, version: 5679 } ]);
|
3522
|
-
|
3523
|
-
// there should be no requests to Locus sent
|
3524
|
-
await waitForMaxPossibleBackoffTime(locusInfo.hashTreeParser.dataSets);
|
3525
|
-
assert.notCalled(webex.request);
|
3526
|
-
});
|
3527
|
-
|
3528
|
-
it('does a sync if hashes don\'t match after a timer fires', async () => {
|
3529
|
-
const atdUnmutedDataSetUrl = mockFullLocus.dataSets[2].url;
|
3530
|
-
|
3531
|
-
locusInfo.initialSetup(mockFullLocus.locus, mockFullLocus.dataSets);
|
3532
|
-
|
3533
|
-
// simulate a hash tree message for a participant
|
3534
|
-
locusInfo.parse(mockMeeting, {
|
3535
|
-
"locusUrl" : "https://locus.wbx2.com/locus/api/v1/loci/dbe6eeb9-49c7-4727-bdb1-1c59fa6e56d2",
|
3536
|
-
"locusSessionId" : "fe3d019c-08ca-0f21-919f-f2cc646030ae",
|
3537
|
-
"dataSets" : [ {
|
3538
|
-
"url" : atdUnmutedDataSetUrl,
|
3539
|
-
"name" : "atd-unmuted",
|
3540
|
-
"root" : "deadbeef", // wrong to trigger a sync
|
3541
|
-
"version" : 5738696122316,
|
3542
|
-
"leafCount" : 4,
|
3543
|
-
"idleMs" : 25000,
|
3544
|
-
"backoff" : {
|
3545
|
-
"maxMs" : 500,
|
3546
|
-
"exponent" : 0.5
|
3547
|
-
}
|
3548
|
-
} ],
|
3549
|
-
"locusStateElements" : [ {
|
3550
|
-
"htMeta" : {
|
3551
|
-
"elementId" : {
|
3552
|
-
"type" : "PARTICIPANT",
|
3553
|
-
"id" : 2,
|
3554
|
-
"version" : 5679
|
3555
|
-
},
|
3556
|
-
"dataSetNames" : [ "attendees", "atd-unmuted" ]
|
3557
|
-
},
|
3558
|
-
"data" : "{\"isCreator\":false,\"url\":\"https://locus.wbx2.com/locus/api/v1/loci/dbe6eeb9-49c7-4727-bdb1-1c59fa6e56d2/participant/18ef210c-234a-49ac-83d6-1803bc401bc9\",\"id\":\"18ef210c-234a-49ac-83d6-1803bc401bc9\",\"guest\":false,\"resourceGuest\":false,\"moderator\":false,\"panelist\":false}"
|
3559
|
-
}]
|
3560
|
-
});
|
3561
|
-
|
3562
|
-
// main and self should be unchanged
|
3563
|
-
assert.deepEqual(Object.keys(locusInfo.hashTreeParser.dataSets), ['main', 'self', 'atd-unmuted']);
|
3564
|
-
assert.deepEqual(locusInfo.hashTreeParser.dataSets['main'].hashTree.getLeafData(0), [ { type: 'LOCUS', id: 0, version: 5678 } ]);
|
3565
|
-
assert.deepEqual(locusInfo.hashTreeParser.dataSets['self'].hashTree.getLeafData(0), [ { type: 'SELF', id: 4, version: 5678 } ]);
|
3566
|
-
|
3567
|
-
// participant should be updated
|
3568
|
-
assert.deepEqual(locusInfo.hashTreeParser.dataSets['atd-unmuted'].hashTree.getLeafData(2), [ { type: 'PARTICIPANT', id: 2, version: 5679 } ]);
|
3569
|
-
|
3570
|
-
await testUtils.flushPromises();
|
3571
|
-
|
3572
|
-
// the root hash doesn't match, but we shouldn't send a request to Locus for hashes just yet
|
3573
|
-
assert.notCalled(webex.request);
|
3574
|
-
|
3575
|
-
webex.request.callsFake(async (options) => {
|
3576
|
-
if (options?.method === 'GET' && options?.uri?.endsWith('/hashtree')) {
|
3577
|
-
return {
|
3578
|
-
body: {
|
3579
|
-
hashes: [
|
3580
|
-
'178bff6e3344f551a811712c57a9eac3',
|
3581
|
-
'b113a76304e3a7121afecfe1606ee1c1',
|
3582
|
-
'ae70773ebb3be3653209648071b9bdad',
|
3583
|
-
'99aa06d3014798d86001c324468d497f',
|
3584
|
-
'99aa06d3014798d86001c324468d497f',
|
3585
|
-
'deadbeef', // wrong hash that should cause the participant with id=2 to be deemed out of sync
|
3586
|
-
'99aa06d3014798d86001c324468d497f'
|
3587
|
-
]
|
3588
|
-
}
|
3589
|
-
};
|
3590
|
-
} else if (options?.method === 'POST' && options?.uri?.endsWith('/sync')) {
|
3591
|
-
return {
|
3592
|
-
body: {},
|
3593
|
-
statusCode: 202,
|
3594
|
-
};
|
3595
|
-
}
|
3596
|
-
return {};
|
3597
|
-
});
|
3598
|
-
|
3599
|
-
// only after timeout there should be requests to get hashes and sync sent to Locus
|
3600
|
-
await waitForMaxPossibleBackoffTime(locusInfo.hashTreeParser.dataSets);
|
3601
|
-
assert.calledTwice(webex.request);
|
3602
|
-
|
3603
|
-
const firstCallArgs = webex.request.getCall(0).args[0];
|
3604
|
-
const secondCallArgs = webex.request.getCall(1).args[0];
|
3605
|
-
|
3606
|
-
assert.deepEqual(firstCallArgs, {method: 'GET', uri: `${atdUnmutedDataSetUrl}/hashtree`});
|
3607
|
-
|
3608
|
-
assert.deepEqual(secondCallArgs, {method: 'POST', uri: `${atdUnmutedDataSetUrl}/sync`,
|
3609
|
-
body: {
|
3610
|
-
dataSet: {
|
3611
|
-
name: 'atd-unmuted',
|
3612
|
-
leafCount: 16,
|
3613
|
-
root: '178bff6e3344f551a811712c57a9eac3',
|
3614
|
-
},
|
3615
|
-
leafDataEntries: [{
|
3616
|
-
leafIndex: 2,
|
3617
|
-
elementIds: [
|
3618
|
-
{
|
3619
|
-
id: 2,
|
3620
|
-
type: "PARTICIPANT",
|
3621
|
-
version: 5679
|
3622
|
-
}
|
3623
|
-
],
|
3624
|
-
}]
|
3625
|
-
}
|
3626
|
-
});
|
3627
|
-
});
|
3628
|
-
|
3629
|
-
it('handles end meeting message correctly', async () => {
|
3630
|
-
});
|
3631
|
-
it('handles heartbeat messages correctly', async () => {
|
3632
|
-
});
|
3633
|
-
|
3634
|
-
});
|
3635
3278
|
});
|
3636
3279
|
});
|
@@ -32,6 +32,9 @@ describe('plugin-meetings', () => {
|
|
32
32
|
isClosedCaptionActive: null,
|
33
33
|
canStartManualCaption: null,
|
34
34
|
canStopManualCaption: null,
|
35
|
+
isLocalRecordingStarted: null,
|
36
|
+
isLocalRecordingStopped: null,
|
37
|
+
isLocalRecordingPaused: null,
|
35
38
|
isManualCaptionActive: null,
|
36
39
|
isPremiseRecordingEnabled: null,
|
37
40
|
isSaveTranscriptsEnabled: null,
|
@@ -129,6 +132,9 @@ describe('plugin-meetings', () => {
|
|
129
132
|
'canPauseRecording',
|
130
133
|
'canResumeRecording',
|
131
134
|
'canStopRecording',
|
135
|
+
'isLocalRecordingStarted',
|
136
|
+
'isLocalRecordingStopped',
|
137
|
+
'isLocalRecordingPaused',
|
132
138
|
'canSetMuteOnEntry',
|
133
139
|
'canUnsetMuteOnEntry',
|
134
140
|
'canSetDisallowUnmute',
|