@webex/plugin-meetings 3.0.0-stream-classes.4 → 3.0.0-stream-classes.5

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.
Files changed (44) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/constants.js +3 -1
  4. package/dist/constants.js.map +1 -1
  5. package/dist/interpretation/index.js +1 -1
  6. package/dist/interpretation/siLanguage.js +1 -1
  7. package/dist/locus-info/index.js +25 -1
  8. package/dist/locus-info/index.js.map +1 -1
  9. package/dist/locus-info/parser.js +5 -0
  10. package/dist/locus-info/parser.js.map +1 -1
  11. package/dist/meeting/index.js +72 -15
  12. package/dist/meeting/index.js.map +1 -1
  13. package/dist/meeting/request.js +1 -1
  14. package/dist/meeting/request.js.map +1 -1
  15. package/dist/metrics/constants.js +3 -1
  16. package/dist/metrics/constants.js.map +1 -1
  17. package/dist/multistream/remoteMediaManager.js +46 -9
  18. package/dist/multistream/remoteMediaManager.js.map +1 -1
  19. package/dist/types/constants.d.ts +1 -0
  20. package/dist/types/meeting/index.d.ts +16 -2
  21. package/dist/types/meeting/locusMediaRequest.d.ts +1 -2
  22. package/dist/types/meeting/request.d.ts +2 -1
  23. package/dist/types/meeting/util.d.ts +9 -1
  24. package/dist/types/metrics/constants.d.ts +3 -0
  25. package/dist/types/multistream/remoteMediaManager.d.ts +9 -1
  26. package/dist/types/reachability/index.d.ts +0 -6
  27. package/dist/types/reachability/request.d.ts +1 -1
  28. package/dist/types/roap/request.d.ts +2 -1
  29. package/package.json +1 -1
  30. package/src/constants.ts +1 -0
  31. package/src/locus-info/index.ts +33 -2
  32. package/src/locus-info/parser.ts +7 -0
  33. package/src/meeting/index.ts +59 -16
  34. package/src/meeting/request.ts +1 -1
  35. package/src/metrics/constants.ts +2 -0
  36. package/src/multistream/remoteMediaManager.ts +41 -4
  37. package/test/integration/spec/converged-space-meetings.js +7 -7
  38. package/test/integration/spec/journey.js +85 -103
  39. package/test/integration/spec/space-meeting.js +9 -9
  40. package/test/unit/spec/locus-info/index.js +118 -1
  41. package/test/unit/spec/meeting/index.js +88 -25
  42. package/test/unit/spec/meetings/index.js +2 -2
  43. package/test/unit/spec/multistream/remoteMediaManager.ts +10 -2
  44. package/test/utils/integrationTestUtils.js +4 -4
@@ -1406,9 +1406,10 @@ describe('plugin-meetings', () => {
1406
1406
  });
1407
1407
 
1408
1408
  it('should reject if waitForMediaConnectionConnected() rejects', async () => {
1409
- webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode = sinon
1409
+ const FAKE_ERROR = {fatal: true};
1410
+ const getErrorPayloadForClientErrorCodeStub = webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode = sinon
1410
1411
  .stub()
1411
- .returns({});
1412
+ .returns(FAKE_ERROR);
1412
1413
  meeting.meetingState = 'ACTIVE';
1413
1414
  meeting.mediaProperties.waitForMediaConnectionConnected.rejects(new Error('fake error'));
1414
1415
 
@@ -1422,14 +1423,14 @@ describe('plugin-meetings', () => {
1422
1423
  errorThrown = true;
1423
1424
  });
1424
1425
 
1426
+ assert.calledOnceWithExactly(getErrorPayloadForClientErrorCodeStub, {clientErrorCode: 2004});
1425
1427
  assert.calledTwice(webex.internal.newMetrics.submitClientEvent);
1426
-
1427
1428
  assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
1428
1429
  name: 'client.ice.end',
1429
1430
  payload: {
1430
1431
  canProceed: false,
1431
1432
  icePhase: 'JOIN_MEETING_FINAL',
1432
- errors: [{}],
1433
+ errors: [FAKE_ERROR],
1433
1434
  },
1434
1435
  options: {
1435
1436
  meetingId: meeting.id,
@@ -4487,20 +4488,22 @@ describe('plugin-meetings', () => {
4487
4488
 
4488
4489
  describe('submitClientEvent on connectionFailed', () => {
4489
4490
  it('sends client.ice.end when connectionFailed on CONNECTION_STATE_CHANGED event', () => {
4490
- webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode =
4491
- sinon.stub().returns({});
4491
+ const FAKE_ERROR = {fatal: true};
4492
+ const getErrorPayloadForClientErrorCodeStub = webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode = sinon
4493
+ .stub()
4494
+ .returns(FAKE_ERROR);
4492
4495
  meeting.setupMediaConnectionListeners();
4493
4496
  eventListeners[Event.CONNECTION_STATE_CHANGED]({
4494
4497
  state: 'Failed',
4495
4498
  });
4499
+ assert.calledOnceWithExactly(getErrorPayloadForClientErrorCodeStub, {clientErrorCode: 2004});
4496
4500
  assert.calledOnce(webex.internal.newMetrics.submitClientEvent);
4497
-
4498
4501
  assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
4499
4502
  name: 'client.ice.end',
4500
4503
  payload: {
4501
4504
  canProceed: false,
4502
4505
  icePhase: 'IN_MEETING',
4503
- errors: [{}],
4506
+ errors: [FAKE_ERROR],
4504
4507
  },
4505
4508
  options: {
4506
4509
  meetingId: meeting.id,
@@ -5559,29 +5562,40 @@ describe('plugin-meetings', () => {
5559
5562
  });
5560
5563
  });
5561
5564
 
5565
+ describe('#setPermissionTokenPayload', () => {
5566
+ it('sets correctly', () => {
5567
+ assert.notOk(meeting.permissionTokenPayload);
5568
+
5569
+ const permissionTokenPayloadData = {permission: {userPolicies: {a: true}}, exp: '1234'};
5570
+
5571
+ const jwtDecodeStub = sinon.stub(jwt, 'decode').returns(permissionTokenPayloadData);
5572
+
5573
+ meeting.setPermissionTokenPayload();
5574
+
5575
+ assert.calledOnce(jwtDecodeStub);
5576
+ assert.deepEqual(meeting.permissionTokenPayload, permissionTokenPayloadData);
5577
+ });
5578
+ });
5579
+
5562
5580
  describe('#setSelfUserPolicies', () => {
5563
5581
  it('sets correctly when policy data is present in token', () => {
5564
5582
  assert.notOk(meeting.selfUserPolicies);
5565
5583
 
5566
- const dummyToken = 'some data';
5567
5584
  const policyData = {permission: {userPolicies: {a: true}}};
5585
+ meeting.permissionTokenPayload = policyData;
5568
5586
 
5569
- sinon.stub(jwt, 'decode').returns(policyData);
5570
-
5571
- meeting.setSelfUserPolicies(dummyToken);
5587
+ meeting.setSelfUserPolicies();
5572
5588
 
5573
- assert.deepEqual(meeting.selfUserPolicies, {a: true});
5589
+ assert.deepEqual(meeting.selfUserPolicies, policyData.permission.userPolicies);
5574
5590
  });
5575
5591
 
5576
5592
  it('handles missing permission data', () => {
5577
5593
  assert.notOk(meeting.selfUserPolicies);
5578
5594
 
5579
- const dummyToken = 'some data';
5580
5595
  const policyData = {};
5596
+ meeting.permissionTokenPayload = policyData;
5581
5597
 
5582
- sinon.stub(jwt, 'decode').returns(policyData);
5583
-
5584
- meeting.setSelfUserPolicies(dummyToken);
5598
+ meeting.setSelfUserPolicies();
5585
5599
 
5586
5600
  assert.deepEqual(meeting.selfUserPolicies, undefined);
5587
5601
  });
@@ -5589,12 +5603,10 @@ describe('plugin-meetings', () => {
5589
5603
  it('handles missing policy data', () => {
5590
5604
  assert.notOk(meeting.selfUserPolicies);
5591
5605
 
5592
- const dummyToken = 'some data';
5593
5606
  const policyData = {permission: {}};
5607
+ meeting.permissionTokenPayload = policyData;
5594
5608
 
5595
- sinon.stub(jwt, 'decode').returns(policyData);
5596
-
5597
- meeting.setSelfUserPolicies(dummyToken);
5609
+ meeting.setSelfUserPolicies();
5598
5610
 
5599
5611
  assert.deepEqual(meeting.selfUserPolicies, undefined);
5600
5612
  });
@@ -5654,19 +5666,37 @@ describe('plugin-meetings', () => {
5654
5666
  assert.equal(meeting.owner, expectedInfoToParse.owner);
5655
5667
  assert.equal(meeting.permissionToken, expectedInfoToParse.permissionToken);
5656
5668
  assert.deepEqual(meeting.selfUserPolicies, expectedInfoToParse.selfUserPolicies);
5669
+
5670
+ if(expectedInfoToParse.permissionTokenPayload) {
5671
+ assert.deepEqual(meeting.permissionTokenPayload, expectedInfoToParse.permissionTokenPayload);
5672
+ }
5657
5673
  };
5658
5674
 
5659
5675
  it('should parse meeting info from api return when locus meeting object is not available, set values, and return null', () => {
5660
5676
  meeting.config.experimental = {enableMediaNegotiatedEvent: true};
5661
5677
  meeting.config.experimental.enableUnifiedMeetings = true;
5678
+
5679
+ const expectedPermissionTokenPayload = {
5680
+ exp: "123456",
5681
+ permission: {
5682
+ userPolicies: {
5683
+ a: true
5684
+ }
5685
+ }
5686
+ };
5687
+
5688
+ // generated permissionToken with secret `secret` and
5689
+ // value `JSON.stringify(expectedPermissionTokenPayload)`
5690
+ const permissionToken =
5691
+ 'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0';
5692
+
5662
5693
  const FAKE_MEETING_INFO = {
5663
5694
  body: {
5664
5695
  conversationUrl: uuid1,
5665
5696
  locusUrl: url1,
5666
5697
  meetingJoinUrl: url2,
5667
5698
  meetingNumber: '12345',
5668
- permissionToken:
5669
- 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX0sImlhdCI6MTY4OTE2NDEwMn0.9uL_U7QUdYyMerrgHC_gCKOax2j_bz04u8Ikbv9KiXU',
5699
+ permissionToken,
5670
5700
  sipMeetingUri: test1,
5671
5701
  sipUrl: test1,
5672
5702
  owner: test2,
@@ -5674,6 +5704,7 @@ describe('plugin-meetings', () => {
5674
5704
  };
5675
5705
 
5676
5706
  meeting.parseMeetingInfo(FAKE_MEETING_INFO);
5707
+
5677
5708
  const expectedInfoToParse = {
5678
5709
  conversationUrl: uuid1,
5679
5710
  locusUrl: url1,
@@ -5682,8 +5713,8 @@ describe('plugin-meetings', () => {
5682
5713
  meetingJoinUrl: url2,
5683
5714
  owner: test2,
5684
5715
  selfUserPolicies: {a: true},
5685
- permissionToken:
5686
- 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX0sImlhdCI6MTY4OTE2NDEwMn0.9uL_U7QUdYyMerrgHC_gCKOax2j_bz04u8Ikbv9KiXU',
5716
+ permissionToken,
5717
+ permissionTokenPayload: expectedPermissionTokenPayload
5687
5718
  };
5688
5719
 
5689
5720
  checkParseMeetingInfo(expectedInfoToParse);
@@ -7993,4 +8024,36 @@ describe('plugin-meetings', () => {
7993
8024
  });
7994
8025
  });
7995
8026
  });
8027
+
8028
+ describe('#getPermissionTokenTimeLeftInSec', () => {
8029
+ let now;
8030
+ let clock;
8031
+
8032
+ beforeEach(() => {
8033
+ now = Date.now();
8034
+
8035
+ // mock `new Date()` with constant `now`
8036
+ clock = sinon.useFakeTimers(now);
8037
+ });
8038
+
8039
+ afterEach(() => {
8040
+ clock.restore();
8041
+ })
8042
+
8043
+ it('should return undefined if exp is undefined', () => {
8044
+ assert.equal(meeting.getPermissionTokenTimeLeftInSec(), undefined)
8045
+ });
8046
+
8047
+ it('should return the expected positive exp', () => {
8048
+ // set permission token as now + 1 sec
8049
+ meeting.permissionTokenPayload = {exp: (now + 1000).toString()};
8050
+ assert.equal(meeting.getPermissionTokenTimeLeftInSec(), 1);
8051
+ });
8052
+
8053
+ it('should return the expected negative exp', () => {
8054
+ // set permission token as now - 1 sec
8055
+ meeting.permissionTokenPayload = {exp: (now - 1000).toString()};
8056
+ assert.equal(meeting.getPermissionTokenTimeLeftInSec(), -1);
8057
+ });
8058
+ });
7996
8059
  });
@@ -370,7 +370,7 @@ describe('plugin-meetings', () => {
370
370
 
371
371
  assert.exists(result);
372
372
  assert.instanceOf(result, VirtualBackgroundEffect);
373
- assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'isLoaded', 'options']);
373
+ assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
374
374
  assert.deepEqual(result.options, {
375
375
  mode: 'BLUR',
376
376
  blurStrength: 'STRONG',
@@ -399,7 +399,7 @@ describe('plugin-meetings', () => {
399
399
 
400
400
  assert.exists(result);
401
401
  assert.instanceOf(result, VirtualBackgroundEffect);
402
- assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'isLoaded', 'options']);
402
+ assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
403
403
  assert.deepEqual(result.options, {...effectOptions, authToken: "fake_token"});
404
404
  assert.exists(result.enable);
405
405
  assert.exists(result.disable);
@@ -747,7 +747,11 @@ describe('RemoteMediaManager', () => {
747
747
 
748
748
  assert.calledWith(
749
749
  logger.log,
750
- 'RemoteMediaManager#updateVideoReceiveSlots --> receive slots updated: unused=0, activeSpeaker=6, receiverSelected=4\ngroup: thumbnails\nfake video slot fake video slot fake video slot fake video slot fake video slot fake video slot\nreceiverSelected:\n stage-1: fake video slot\n stage-2: fake video slot\n stage-3: fake video slot\n stage-4: fake video slot\n'
750
+ 'RemoteMediaManager#setLayout --> new layout selected: Stage'
751
+ );
752
+ assert.calledWith(
753
+ logger.log,
754
+ 'RemoteMediaManager#logMainVideoReceiveSlots --> MAIN VIDEO receive slots: unused=0, activeSpeaker=6, receiverSelected=4\ngroup: thumbnails\nfake video slot, fake video slot, fake video slot, fake video slot, fake video slot, fake video slot\nreceiverSelected:\n stage-1: fake video slot\n stage-2: fake video slot\n stage-3: fake video slot\n stage-4: fake video slot\n'
751
755
  );
752
756
  });
753
757
 
@@ -769,7 +773,11 @@ describe('RemoteMediaManager', () => {
769
773
 
770
774
  assert.calledWith(
771
775
  logger.log,
772
- 'RemoteMediaManager#updateVideoReceiveSlots --> receive slots updated: unused=0, activeSpeaker=9, receiverSelected=0\ngroup: main\nfake video slot fake video slot fake video slot fake video slot fake video slot fake video slot fake video slot fake video slot fake video slot\nreceiverSelected:\n'
776
+ 'RemoteMediaManager#setLayout --> new layout selected: AllEqual'
777
+ );
778
+ assert.calledWith(
779
+ logger.log,
780
+ 'RemoteMediaManager#logMainVideoReceiveSlots --> MAIN VIDEO receive slots: unused=0, activeSpeaker=9, receiverSelected=0\ngroup: main\nfake video slot, fake video slot, fake video slot, fake video slot, fake video slot, fake video slot, fake video slot, fake video slot, fake video slot\nreceiverSelected:\n'
773
781
  );
774
782
  });
775
783
 
@@ -6,7 +6,7 @@ const addMedia = async (user, options = {}) => {
6
6
  const {microphone, camera} = options;
7
7
 
8
8
  if (options.multistream) {
9
- await user.meeting.addMedia({localTracks: {microphone, camera}});
9
+ await user.meeting.addMedia({localStreams: {microphone, camera}});
10
10
  } else {
11
11
  const mediaReadyPromises = Array.isArray(options.expectedMediaReadyTypes)
12
12
  ? options.expectedMediaReadyTypes.reduce((output, expectedMediaReadyType) => {
@@ -31,13 +31,13 @@ const addMedia = async (user, options = {}) => {
31
31
 
32
32
  user.meeting.on('media:ready', mediaReady);
33
33
 
34
- await user.meeting.addMedia({localTracks: {microphone, camera}});
34
+ await user.meeting.addMedia({localStreams: {microphone, camera}});
35
35
  await Promise.all(Object.values(mediaReadyPromises).map((defer) => defer.promise));
36
36
  };
37
37
 
38
38
 
39
- assert.exists(user.meeting.mediaProperties.audioTrack, 'audioTrack not present');
40
- assert.exists(user.meeting.mediaProperties.videoTrack, 'videoTrack not present');
39
+ assert.exists(user.meeting.mediaProperties.audioStream, 'audioStream not present');
40
+ assert.exists(user.meeting.mediaProperties.videoStream, 'videoStream not present');
41
41
 
42
42
  };
43
43