@webex/plugin-meetings 3.10.0-webex-services-ready.1 → 3.10.0-webex-services-ready.3

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.
@@ -358,6 +358,76 @@ describe('plugin-meetings', () => {
358
358
  });
359
359
  });
360
360
 
361
+ it('should process locus update correctly when called with updated SELF (webinar non-attendee)', () => {
362
+ const newSelf = {
363
+ id: 'new-self',
364
+ visibleDataSets: ['dataset1', 'dataset2'],
365
+ controls: {
366
+ role: {
367
+ roles: [
368
+ {type: 'PANELIST', hasRole: true},
369
+ {type: 'ATTENDEE', hasRole: false},
370
+ ],
371
+ },
372
+ },
373
+ };
374
+ locusInfo.info.isWebinar = true;
375
+
376
+ // simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
377
+ locusInfoUpdateCallback(OBJECTS_UPDATED, {
378
+ updatedObjects: [{htMeta: {elementId: {type: 'self'}}, data: newSelf}],
379
+ });
380
+
381
+ // check onDeltaLocus() was called with correctly updated locus info
382
+ // without any participant generated
383
+ assert.calledOnceWithExactly(onDeltaLocusStub, {
384
+ ...expectedLocusInfo,
385
+ info: {
386
+ ...expectedLocusInfo.info,
387
+ isWebinar: true,
388
+ },
389
+ self: newSelf,
390
+ });
391
+ });
392
+
393
+ it('should generate a participant when called with updated SELF for webinar attendee', () => {
394
+ const newSelf = {
395
+ id: 'new-self',
396
+ visibleDataSets: ['dataset1', 'dataset2'],
397
+ controls: {
398
+ role: {
399
+ roles: [
400
+ {type: 'something else - should be ignored', hasRole: true},
401
+ {type: 'ATTENDEE', hasRole: true},
402
+ ],
403
+ },
404
+ },
405
+ };
406
+
407
+ locusInfo.info.isWebinar = true;
408
+
409
+ // simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
410
+ locusInfoUpdateCallback(OBJECTS_UPDATED, {
411
+ updatedObjects: [{htMeta: {elementId: {type: 'self'}}, data: newSelf}],
412
+ });
413
+
414
+ // check onDeltaLocus() was called with correctly updated locus info
415
+ // that contains a participant created from self
416
+ assert.calledOnceWithExactly(onDeltaLocusStub, {
417
+ ...expectedLocusInfo,
418
+ info: {
419
+ ...expectedLocusInfo.info,
420
+ isWebinar: true,
421
+ },
422
+ self: newSelf,
423
+ participants: [
424
+ {
425
+ ...newSelf,
426
+ },
427
+ ],
428
+ });
429
+ });
430
+
361
431
  it('should process locus update correctly when called with updated fullState', () => {
362
432
  const newFullState = {
363
433
  id: 'new-fullState',
@@ -394,6 +464,24 @@ describe('plugin-meetings', () => {
394
464
  });
395
465
  });
396
466
 
467
+ it('should process locus update correctly when called with updated links', () => {
468
+ const newLinks = {
469
+ id: 'new-links',
470
+ visibleDataSets: ['dataset1', 'dataset2'],
471
+ };
472
+
473
+ // simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
474
+ locusInfoUpdateCallback(OBJECTS_UPDATED, {
475
+ updatedObjects: [{htMeta: {elementId: {type: 'links'}}, data: newLinks}],
476
+ });
477
+
478
+ // check onDeltaLocus() was called with correctly updated locus info
479
+ assert.calledOnceWithExactly(onDeltaLocusStub, {
480
+ ...expectedLocusInfo,
481
+ links: newLinks,
482
+ });
483
+ });
484
+
397
485
  it('should process locus update correctly when called with updated LOCUS object', () => {
398
486
  // setup new updated locus that has many things missing
399
487
  const newLocusHtMeta = {elementId: {type: 'locus', version: 42}};
@@ -414,6 +502,7 @@ describe('plugin-meetings', () => {
414
502
  info: {id: 'fake-info'},
415
503
  fullState: {id: 'fake-full-state'},
416
504
  self: {id: 'fake-self'},
505
+ links: { id: 'fake-links' },
417
506
  mediaShares: expectedLocusInfo.mediaShares,
418
507
  // and now the new fields
419
508
  ...newLocus,
@@ -459,6 +548,7 @@ describe('plugin-meetings', () => {
459
548
  info: {id: 'fake-info'},
460
549
  fullState: {id: 'fake-full-state'},
461
550
  self: {id: 'fake-self'},
551
+ links: { id: 'fake-links' },
462
552
  mediaShares: expectedLocusInfo.mediaShares,
463
553
  participants: [], // empty means there were no participant updates
464
554
  jsSdkMeta: {removedParticipantIds: []}, // no participants were removed
@@ -492,6 +582,7 @@ describe('plugin-meetings', () => {
492
582
  info: {id: 'fake-info'},
493
583
  fullState: {id: 'fake-full-state'},
494
584
  self: {id: 'fake-self'},
585
+ links: {id: 'fake-links'},
495
586
  mediaShares: expectedLocusInfo.mediaShares,
496
587
  // and now the new fields
497
588
  ...newLocus,
@@ -2759,8 +2850,7 @@ describe('plugin-meetings', () => {
2759
2850
  callOrder.push("updateMeetingInfo");
2760
2851
  });
2761
2852
  sinon.stub(locusInfo, "updateMediaShares");
2762
- sinon.stub(locusInfo, "updateParticipantsUrl");
2763
- sinon.stub(locusInfo, "updateReplace");
2853
+ sinon.stub(locusInfo, "updateReplaces");
2764
2854
  sinon.stub(locusInfo, "updateSelf");
2765
2855
  sinon.stub(locusInfo, "updateLocusUrl").callsFake(() => {
2766
2856
  callOrder.push("updateLocusUrl");
@@ -2768,10 +2858,8 @@ describe('plugin-meetings', () => {
2768
2858
  sinon.stub(locusInfo, "updateAclUrl");
2769
2859
  sinon.stub(locusInfo, "updateBasequence");
2770
2860
  sinon.stub(locusInfo, "updateSequence");
2771
- sinon.stub(locusInfo, "updateMemberShip");
2772
- sinon.stub(locusInfo, "updateIdentifiers");
2773
2861
  sinon.stub(locusInfo, "updateEmbeddedApps");
2774
- sinon.stub(locusInfo, "updateResources");
2862
+ sinon.stub(locusInfo, "updateLinks");
2775
2863
  sinon.stub(locusInfo, "compareAndUpdate");
2776
2864
 
2777
2865
  locusInfo.updateLocusInfo(locus);
@@ -2795,17 +2883,14 @@ describe('plugin-meetings', () => {
2795
2883
  locusInfo.updateHostInfo = sinon.stub();
2796
2884
  locusInfo.updateMeetingInfo = sinon.stub();
2797
2885
  locusInfo.updateMediaShares = sinon.stub();
2798
- locusInfo.updateParticipantsUrl = sinon.stub();
2799
- locusInfo.updateReplace = sinon.stub();
2886
+ locusInfo.updateReplaces = sinon.stub();
2800
2887
  locusInfo.updateSelf = sinon.stub();
2801
2888
  locusInfo.updateLocusUrl = sinon.stub();
2802
2889
  locusInfo.updateAclUrl = sinon.stub();
2803
2890
  locusInfo.updateBasequence = sinon.stub();
2804
2891
  locusInfo.updateSequence = sinon.stub();
2805
- locusInfo.updateMemberShip = sinon.stub();
2806
- locusInfo.updateIdentifiers = sinon.stub();
2807
2892
  locusInfo.updateEmbeddedApps = sinon.stub();
2808
- locusInfo.updateResources = sinon.stub();
2893
+ locusInfo.updateLinks = sinon.stub();
2809
2894
  locusInfo.compareAndUpdate = sinon.stub();
2810
2895
 
2811
2896
  locusInfo.updateLocusInfo(newLocus);
@@ -2817,21 +2902,49 @@ describe('plugin-meetings', () => {
2817
2902
  assert.notCalled(locusInfo.updateHostInfo);
2818
2903
  assert.notCalled(locusInfo.updateMeetingInfo);
2819
2904
  assert.notCalled(locusInfo.updateMediaShares);
2820
- assert.notCalled(locusInfo.updateParticipantsUrl);
2821
- assert.notCalled(locusInfo.updateReplace);
2905
+ assert.notCalled(locusInfo.updateReplaces);
2822
2906
  assert.notCalled(locusInfo.updateSelf);
2823
2907
  assert.notCalled(locusInfo.updateLocusUrl);
2824
2908
  assert.notCalled(locusInfo.updateAclUrl);
2825
2909
  assert.notCalled(locusInfo.updateBasequence);
2826
2910
  assert.notCalled(locusInfo.updateSequence);
2827
- assert.notCalled(locusInfo.updateMemberShip);
2828
- assert.notCalled(locusInfo.updateIdentifiers);
2829
2911
  assert.notCalled(locusInfo.updateEmbeddedApps);
2830
- assert.notCalled(locusInfo.updateResources);
2912
+ assert.notCalled(locusInfo.updateLinks);
2831
2913
  assert.notCalled(locusInfo.compareAndUpdate);
2832
2914
  });
2833
2915
 
2916
+ it('#updateLocusInfo puts the Locus DTO top level properties at the right place in LocusInfo class', () => {
2917
+ // this test verifies that the top-level properties of Locus DTO are copied
2918
+ // into LocusInfo class and set as top level properties too
2919
+ // this is important, because the code handling Locus hass trees relies on it, see updateFromHashTree()
2920
+ const info = {id: 'info id'};
2921
+ const fullState = {id: 'fullState id'};
2922
+ const links = {services: {id: 'service links'}, resources: {id: 'resource links'}};
2923
+ const self = {id: 'self id'};
2924
+ const mediaShares = [{id: 'fake media share'}];
2834
2925
 
2926
+ sinon.stub(SelfUtils, 'getSelves').returns({
2927
+ current: {},
2928
+ previous: {},
2929
+ updates: {},
2930
+ });
2931
+
2932
+ const newLocus = {
2933
+ info,
2934
+ fullState,
2935
+ links,
2936
+ self,
2937
+ mediaShares,
2938
+ };
2939
+
2940
+ locusInfo.updateLocusInfo(newLocus);
2941
+
2942
+ assert.deepEqual(locusInfo.info, newLocus.info);
2943
+ assert.deepEqual(locusInfo.fullState, newLocus.fullState);
2944
+ assert.deepEqual(locusInfo.links, newLocus.links);
2945
+ assert.deepEqual(locusInfo.self, newLocus.self);
2946
+ assert.deepEqual(locusInfo.mediaShares, newLocus.mediaShares);
2947
+ });
2835
2948
 
2836
2949
  it('onFullLocus() updates the working-copy of locus parser', () => {
2837
2950
  const eventType = 'fakeEvent';
@@ -1003,6 +1003,35 @@ describe('plugin-meetings', () => {
1003
1003
  );
1004
1004
  });
1005
1005
 
1006
+ it('should call leave() if addMediaInternal() fails ', async () => {
1007
+ const addMediaError = new Error('fake addMedia error');
1008
+ addMediaError.name = 'TypeError';
1009
+
1010
+ const rejectError = {
1011
+ error: {
1012
+ body: {
1013
+ errorCode: 2729,
1014
+ message: 'fake addMedia error',
1015
+ name: 'TypeError'
1016
+ }
1017
+ }
1018
+ };
1019
+ meeting.addMediaInternal.rejects(addMediaError);
1020
+ sinon.stub(meeting, 'leave').resolves();
1021
+
1022
+ await assert.isRejected(
1023
+ meeting.joinWithMedia({
1024
+ joinOptions,
1025
+ mediaOptions,
1026
+ }),
1027
+ rejectError
1028
+ );
1029
+
1030
+ assert.calledOnce(meeting.join);
1031
+ assert.calledOnce(meeting.addMediaInternal);
1032
+ assert.calledOnce(Metrics.sendBehavioralMetric);
1033
+ });
1034
+
1006
1035
  it('should not call leave() if addMediaInternal() fails the first time and succeeds the second time and should only call join() once', async () => {
1007
1036
  const addMediaError = new Error('fake addMedia error');
1008
1037
  const leaveStub = sinon.stub(meeting, 'leave');