@webex/plugin-meetings 3.0.0-beta.170 → 3.0.0-beta.172

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 (40) hide show
  1. package/README.md +0 -6
  2. package/dist/breakouts/breakout.js +1 -1
  3. package/dist/breakouts/index.js +1 -1
  4. package/dist/index.js +12 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/interpretation/index.js +1 -1
  7. package/dist/interpretation/siLanguage.js +1 -1
  8. package/dist/media/index.js +3 -3
  9. package/dist/media/index.js.map +1 -1
  10. package/dist/media/properties.js +22 -5
  11. package/dist/media/properties.js.map +1 -1
  12. package/dist/meeting/index.js +529 -415
  13. package/dist/meeting/index.js.map +1 -1
  14. package/dist/member/index.js +15 -0
  15. package/dist/member/index.js.map +1 -1
  16. package/dist/member/types.js +11 -1
  17. package/dist/member/types.js.map +1 -1
  18. package/dist/member/util.js +15 -0
  19. package/dist/member/util.js.map +1 -1
  20. package/dist/reconnection-manager/index.js +1 -2
  21. package/dist/reconnection-manager/index.js.map +1 -1
  22. package/dist/types/index.d.ts +1 -1
  23. package/dist/types/media/properties.d.ts +10 -3
  24. package/dist/types/meeting/index.d.ts +41 -9
  25. package/dist/types/member/index.d.ts +2 -1
  26. package/dist/types/member/types.d.ts +11 -0
  27. package/package.json +20 -20
  28. package/src/index.ts +2 -0
  29. package/src/media/index.ts +11 -5
  30. package/src/media/properties.ts +24 -5
  31. package/src/meeting/index.ts +210 -77
  32. package/src/member/index.ts +17 -1
  33. package/src/member/types.ts +14 -0
  34. package/src/member/util.ts +23 -1
  35. package/src/reconnection-manager/index.ts +4 -1
  36. package/test/integration/spec/journey.js +9 -9
  37. package/test/unit/spec/media/index.ts +13 -3
  38. package/test/unit/spec/meeting/index.js +106 -15
  39. package/test/unit/spec/member/index.js +36 -13
  40. package/test/unit/spec/member/util.js +31 -0
@@ -657,7 +657,7 @@ skipInNode(describe)('plugin-meetings', () => {
657
657
  await startedSharingRemote;
658
658
  await bobReceivesMembersUpdate;
659
659
 
660
- assert.equal(alice.meeting.isSharing, true);
660
+ assert.equal(alice.meeting.screenShareFloorState, 'floor_request_granted');
661
661
  assert.equal(alice.meeting.shareStatus, 'local_share_active');
662
662
  assert.equal(bob.meeting.shareStatus, 'remote_share_active');
663
663
  console.log(
@@ -699,7 +699,7 @@ skipInNode(describe)('plugin-meetings', () => {
699
699
  localTracks.alice.screenShare.video.stop();
700
700
  localTracks.alice.screenShare.video = undefined;
701
701
 
702
- assert.equal(bob.meeting.isSharing, true);
702
+ assert.equal(bob.meeting.screenShareFloorState, 'floor_request_granted');
703
703
  assert.equal(bob.meeting.shareStatus, 'local_share_active');
704
704
  assert.equal(alice.meeting.shareStatus, 'remote_share_active');
705
705
 
@@ -720,7 +720,7 @@ skipInNode(describe)('plugin-meetings', () => {
720
720
  localTracks.bob.screenShare.video.stop();
721
721
  localTracks.bob.screenShare.video = undefined;
722
722
 
723
- assert.equal(bob.meeting.isSharing, false);
723
+ assert.equal(bob.meeting.screenShareFloorState, 'floor_released');
724
724
  assert.equal(bob.meeting.shareStatus, 'no_share');
725
725
  assert.equal(alice.meeting.shareStatus, 'no_share');
726
726
 
@@ -750,7 +750,7 @@ skipInNode(describe)('plugin-meetings', () => {
750
750
  );
751
751
  }),
752
752
  ]).then(() => {
753
- assert.equal(alice.meeting.isSharing, false);
753
+ assert.equal(alice.meeting.screenShareFloorState, 'floor_released');
754
754
  assert.equal(alice.meeting.shareStatus, 'whiteboard_share_active');
755
755
  assert.equal(bob.meeting.shareStatus, 'whiteboard_share_active');
756
756
  }));
@@ -778,7 +778,7 @@ skipInNode(describe)('plugin-meetings', () => {
778
778
  );
779
779
  }),
780
780
  ]).then(() => {
781
- assert.equal(bob.meeting.isSharing, false);
781
+ assert.equal(bob.meeting.screenShareFloorState, 'floor_released');
782
782
  assert.equal(alice.meeting.shareStatus, 'whiteboard_share_active');
783
783
  assert.equal(bob.meeting.shareStatus, 'whiteboard_share_active');
784
784
  }));
@@ -795,7 +795,7 @@ skipInNode(describe)('plugin-meetings', () => {
795
795
  {scope: alice.meeting, event: 'meeting:stoppedSharingWhiteboard'},
796
796
  ]),
797
797
  ]).then(() => {
798
- assert.equal(bob.meeting.isSharing, false);
798
+ assert.equal(bob.meeting.screenShareFloorState, 'floor_released');
799
799
  assert.equal(bob.meeting.shareStatus, 'no_share');
800
800
  assert.equal(alice.meeting.shareStatus, 'no_share');
801
801
  }));
@@ -823,7 +823,7 @@ skipInNode(describe)('plugin-meetings', () => {
823
823
  );
824
824
  }),
825
825
  ]).then(() => {
826
- assert.equal(alice.meeting.isSharing, false);
826
+ assert.equal(alice.meeting.screenShareFloorState, 'floor_released');
827
827
  assert.equal(alice.meeting.shareStatus, 'whiteboard_share_active');
828
828
  assert.equal(bob.meeting.shareStatus, 'whiteboard_share_active');
829
829
  }));
@@ -854,7 +854,7 @@ skipInNode(describe)('plugin-meetings', () => {
854
854
  await startedSharingRemote;
855
855
  await aliceReceivesMembersUpdate;
856
856
 
857
- assert.equal(bob.meeting.isSharing, true);
857
+ assert.equal(bob.meeting.screenShareFloorState, 'floor_request_granted');
858
858
  assert.equal(bob.meeting.shareStatus, 'local_share_active');
859
859
  assert.equal(alice.meeting.shareStatus, 'remote_share_active');
860
860
 
@@ -884,7 +884,7 @@ skipInNode(describe)('plugin-meetings', () => {
884
884
  );
885
885
  }),
886
886
  ]).then(() => {
887
- assert.equal(bob.meeting.isSharing, false);
887
+ assert.equal(bob.meeting.screenShareFloorState, 'floor_released');
888
888
  assert.equal(alice.meeting.shareStatus, 'whiteboard_share_active');
889
889
  assert.equal(bob.meeting.shareStatus, 'whiteboard_share_active');
890
890
  }));
@@ -17,6 +17,14 @@ describe('createMediaConnection', () => {
17
17
  id: 'video track',
18
18
  underlyingTrack: 'underlying video track',
19
19
  };
20
+ const fakeShareVideoTrack = {
21
+ id: 'share video track',
22
+ underlyingTrack: 'underlying share video track',
23
+ };
24
+ const fakeShareAudioTrack = {
25
+ id: 'share audio track',
26
+ underlyingTrack: 'underlying share audio track',
27
+ };
20
28
 
21
29
  afterEach(() => {
22
30
  sinon.restore();
@@ -44,7 +52,8 @@ describe('createMediaConnection', () => {
44
52
  },
45
53
  audioTrack: fakeAudioTrack,
46
54
  videoTrack: fakeVideoTrack,
47
- shareTrack: null,
55
+ shareVideoTrack: null,
56
+ shareAudioTrack: null,
48
57
  },
49
58
  remoteQualityLevel: 'HIGH',
50
59
  enableRtx: ENABLE_RTX,
@@ -257,7 +266,8 @@ describe('createMediaConnection', () => {
257
266
  },
258
267
  audioTrack: fakeAudioTrack,
259
268
  videoTrack: null,
260
- shareTrack: fakeVideoTrack,
269
+ shareVideoTrack: fakeShareVideoTrack,
270
+ shareAudioTrack: fakeShareAudioTrack,
261
271
  },
262
272
  remoteQualityLevel: 'HIGH',
263
273
  enableRtx: ENABLE_RTX,
@@ -288,7 +298,7 @@ describe('createMediaConnection', () => {
288
298
  localTracks: {
289
299
  audio: fakeAudioTrack.underlyingTrack,
290
300
  video: undefined,
291
- screenShareVideo: fakeVideoTrack.underlyingTrack,
301
+ screenShareVideo: fakeShareVideoTrack.underlyingTrack,
292
302
  },
293
303
  direction: {
294
304
  audio: 'sendrecv',
@@ -1707,6 +1707,7 @@ describe('plugin-meetings', () => {
1707
1707
  audio: undefined,
1708
1708
  video: undefined,
1709
1709
  screenShareVideo: undefined,
1710
+ screenShareAudio: undefined,
1710
1711
  },
1711
1712
  direction: {
1712
1713
  audio: 'sendrecv',
@@ -1735,6 +1736,7 @@ describe('plugin-meetings', () => {
1735
1736
  audio: fakeMicrophoneTrack,
1736
1737
  video: undefined,
1737
1738
  screenShareVideo: undefined,
1739
+ screenShareAudio: undefined,
1738
1740
  },
1739
1741
  direction: {
1740
1742
  audio: 'sendrecv',
@@ -1765,6 +1767,7 @@ describe('plugin-meetings', () => {
1765
1767
  audio: fakeMicrophoneTrack,
1766
1768
  video: undefined,
1767
1769
  screenShareVideo: undefined,
1770
+ screenShareAudio: undefined,
1768
1771
  },
1769
1772
  direction: {
1770
1773
  audio: 'sendrecv',
@@ -1793,6 +1796,7 @@ describe('plugin-meetings', () => {
1793
1796
  audio: fakeMicrophoneTrack,
1794
1797
  video: undefined,
1795
1798
  screenShareVideo: undefined,
1799
+ screenShareAudio: undefined,
1796
1800
  },
1797
1801
  direction: {
1798
1802
  audio: 'inactive',
@@ -1821,6 +1825,7 @@ describe('plugin-meetings', () => {
1821
1825
  audio: undefined,
1822
1826
  video: undefined,
1823
1827
  screenShareVideo: undefined,
1828
+ screenShareAudio: undefined,
1824
1829
  },
1825
1830
  direction: {
1826
1831
  audio: 'inactive',
@@ -2270,7 +2275,7 @@ describe('plugin-meetings', () => {
2270
2275
  meeting.locusInfo.mediaShares = [{name: 'content', url: url1}];
2271
2276
  meeting.locusInfo.self = {url: url1};
2272
2277
  meeting.meetingRequest.changeMeetingFloor = sinon.stub().returns(Promise.resolve());
2273
- meeting.mediaProperties.shareTrack = {}
2278
+ meeting.mediaProperties.shareVideoTrack = {};
2274
2279
  meeting.mediaProperties.mediaDirection.sendShare = true;
2275
2280
  meeting.state = 'JOINED';
2276
2281
  });
@@ -2337,7 +2342,7 @@ describe('plugin-meetings', () => {
2337
2342
  meeting.video = { enable: sinon.stub()};
2338
2343
  meeting.mediaProperties.audioTrack = createFakeLocalTrack();
2339
2344
  meeting.mediaProperties.videoTrack = createFakeLocalTrack();
2340
- meeting.mediaProperties.shareTrack = createFakeLocalTrack();
2345
+ meeting.mediaProperties.shareVideoTrack = createFakeLocalTrack();
2341
2346
  meeting.mediaProperties.mediaDirection = {
2342
2347
  sendAudio: true,
2343
2348
  sendVideo: true,
@@ -2408,7 +2413,7 @@ describe('plugin-meetings', () => {
2408
2413
  localTracks: {
2409
2414
  audio: meeting.mediaProperties.audioTrack.underlyingTrack,
2410
2415
  video: meeting.mediaProperties.videoTrack.underlyingTrack,
2411
- screenShareVideo: meeting.mediaProperties.shareTrack.underlyingTrack,
2416
+ screenShareVideo: meeting.mediaProperties.shareVideoTrack.underlyingTrack,
2412
2417
  },
2413
2418
  direction: {
2414
2419
  audio: 'inactive',
@@ -3624,6 +3629,7 @@ describe('plugin-meetings', () => {
3624
3629
  describe('Local tracks publishing', () => {
3625
3630
  let audioTrack;
3626
3631
  let videoTrack;
3632
+ let audioShareTrack;
3627
3633
  let videoShareTrack;
3628
3634
  let createMuteStateStub;
3629
3635
  let LocalDisplayTrackConstructorStub;
@@ -3646,6 +3652,12 @@ describe('plugin-meetings', () => {
3646
3652
  on: sinon.stub(),
3647
3653
  off: sinon.stub(),
3648
3654
  };
3655
+ audioShareTrack = {
3656
+ id: 'share track',
3657
+ on: sinon.stub(),
3658
+ off: sinon.stub(),
3659
+ getSettings: sinon.stub(),
3660
+ }
3649
3661
  videoShareTrack = {
3650
3662
  id: 'share track',
3651
3663
  on: sinon.stub(),
@@ -3734,7 +3746,18 @@ describe('plugin-meetings', () => {
3734
3746
  meeting.mediaProperties.webrtcMediaConnection.publishTrack,
3735
3747
  track
3736
3748
  );
3737
- assert.equal(meeting.mediaProperties.shareTrack, track);
3749
+ assert.equal(meeting.mediaProperties.shareVideoTrack, track);
3750
+ assert.equal(meeting.mediaProperties.mediaDirection.sendShare, true);
3751
+ };
3752
+
3753
+ const checkScreenShareAudioPublished = (track) => {
3754
+ assert.calledOnce(meeting.requestScreenShareFloor);
3755
+
3756
+ assert.calledWith(
3757
+ meeting.mediaProperties.webrtcMediaConnection.publishTrack,
3758
+ track
3759
+ );
3760
+ assert.equal(meeting.mediaProperties.shareAudioTrack, track);
3738
3761
  assert.equal(meeting.mediaProperties.mediaDirection.sendShare, true);
3739
3762
  };
3740
3763
 
@@ -3744,6 +3767,31 @@ describe('plugin-meetings', () => {
3744
3767
  assert.calledOnce(meeting.mediaProperties.webrtcMediaConnection.publishTrack);
3745
3768
  checkScreenShareVideoPublished(videoShareTrack);
3746
3769
  });
3770
+
3771
+ it('requests screen share floor and publishes the screen share audio track', async () => {
3772
+ await meeting.publishTracks({screenShare: {audio: audioShareTrack}});
3773
+
3774
+ assert.calledOnce(meeting.mediaProperties.webrtcMediaConnection.publishTrack);
3775
+ checkScreenShareAudioPublished(audioShareTrack);
3776
+ });
3777
+
3778
+ it('does not request screen share floor when publishing video share track if already sharing audio', async () => {
3779
+ await meeting.publishTracks({screenShare: {audio: audioShareTrack}});
3780
+ assert.calledOnce(meeting.requestScreenShareFloor);
3781
+
3782
+ meeting.requestScreenShareFloor.reset();
3783
+ await meeting.publishTracks({screenShare: {video: videoShareTrack}});
3784
+ assert.notCalled(meeting.requestScreenShareFloor);
3785
+ })
3786
+
3787
+ it('does not request screen share floor when publishing audio share track if already sharing video', async () => {
3788
+ await meeting.publishTracks({screenShare: {video: videoShareTrack}});
3789
+ assert.calledOnce(meeting.requestScreenShareFloor);
3790
+
3791
+ meeting.requestScreenShareFloor.reset();
3792
+ await meeting.publishTracks({screenShare: {audio: audioShareTrack}});
3793
+ assert.notCalled(meeting.requestScreenShareFloor);
3794
+ })
3747
3795
 
3748
3796
  it('updates MuteState instance and publishes the track for main audio', async () => {
3749
3797
  await meeting.publishTracks({microphone: audioTrack});
@@ -3765,13 +3813,15 @@ describe('plugin-meetings', () => {
3765
3813
  camera: videoTrack,
3766
3814
  screenShare: {
3767
3815
  video: videoShareTrack,
3816
+ audio: audioShareTrack,
3768
3817
  },
3769
3818
  });
3770
3819
 
3771
- assert.calledThrice(meeting.mediaProperties.webrtcMediaConnection.publishTrack);
3820
+ assert.callCount(meeting.mediaProperties.webrtcMediaConnection.publishTrack, 4);
3772
3821
  checkAudioPublished(audioTrack);
3773
3822
  checkVideoPublished(videoTrack);
3774
3823
  checkScreenShareVideoPublished(videoShareTrack);
3824
+ checkScreenShareAudioPublished(audioShareTrack);
3775
3825
  });
3776
3826
  });
3777
3827
  it('creates instance and publishes with annotation info', async () => {
@@ -3788,7 +3838,7 @@ describe('plugin-meetings', () => {
3788
3838
  await meeting.publishTracks({
3789
3839
  microphone: audioTrack,
3790
3840
  camera: videoTrack,
3791
- screenShare: {video: videoShareTrack},
3841
+ screenShare: {video: videoShareTrack, audio: audioShareTrack},
3792
3842
  });
3793
3843
  });
3794
3844
 
@@ -3812,7 +3862,8 @@ describe('plugin-meetings', () => {
3812
3862
  assert.equal(meeting.mediaProperties.mediaDirection.sendVideo, 'fake value');
3813
3863
  };
3814
3864
 
3815
- const checkScreenShareVideoUnpublished = () => {
3865
+ // share direction will remain true if only one of the two share tracks are unpublished
3866
+ const checkScreenShareVideoUnpublished = (shareDirection = true) => {
3816
3867
  assert.calledWith(
3817
3868
  meeting.mediaProperties.webrtcMediaConnection.unpublishTrack,
3818
3869
  videoShareTrack
@@ -3820,24 +3871,38 @@ describe('plugin-meetings', () => {
3820
3871
 
3821
3872
  assert.calledOnce(meeting.requestScreenShareFloor);
3822
3873
 
3823
- assert.equal(meeting.mediaProperties.shareTrack, null);
3824
- assert.equal(meeting.mediaProperties.mediaDirection.sendShare, false);
3874
+ assert.equal(meeting.mediaProperties.shareVideoTrack, null);
3875
+ assert.equal(meeting.mediaProperties.mediaDirection.sendShare, shareDirection);
3876
+ };
3877
+
3878
+ // share direction will remain true if only one of the two share tracks are unpublished
3879
+ const checkScreenShareAudioUnpublished = (shareDirection = true) => {
3880
+ assert.calledWith(
3881
+ meeting.mediaProperties.webrtcMediaConnection.unpublishTrack,
3882
+ audioShareTrack
3883
+ );
3884
+
3885
+ assert.calledOnce(meeting.requestScreenShareFloor);
3886
+
3887
+ assert.equal(meeting.mediaProperties.shareAudioTrack, null);
3888
+ assert.equal(meeting.mediaProperties.mediaDirection.sendShare, shareDirection);
3825
3889
  };
3826
3890
 
3827
3891
  it('fails if there is no media connection', async () => {
3828
3892
  meeting.mediaProperties.webrtcMediaConnection = undefined;
3829
3893
  await assert.isRejected(
3830
- meeting.unpublishTracks([audioTrack, videoTrack, videoShareTrack])
3894
+ meeting.unpublishTracks([audioTrack, videoTrack, videoShareTrack, audioShareTrack])
3831
3895
  );
3832
3896
  });
3833
3897
 
3834
- it('un-publishes the tracks correctly (all 3 together)', async () => {
3835
- await meeting.unpublishTracks([audioTrack, videoTrack, videoShareTrack]);
3898
+ it('un-publishes the tracks correctly (all 4 together)', async () => {
3899
+ await meeting.unpublishTracks([audioTrack, videoTrack, videoShareTrack, audioShareTrack]);
3836
3900
 
3837
- assert.calledThrice(meeting.mediaProperties.webrtcMediaConnection.unpublishTrack);
3901
+ assert.equal(meeting.mediaProperties.webrtcMediaConnection.unpublishTrack.callCount, 4);
3838
3902
  checkAudioUnpublished();
3839
3903
  checkVideoUnpublished();
3840
- checkScreenShareVideoUnpublished();
3904
+ checkScreenShareVideoUnpublished(false);
3905
+ checkScreenShareAudioUnpublished(false);
3841
3906
  });
3842
3907
 
3843
3908
  it('un-publishes the audio track correctly', async () => {
@@ -3860,6 +3925,30 @@ describe('plugin-meetings', () => {
3860
3925
  assert.calledOnce(meeting.mediaProperties.webrtcMediaConnection.unpublishTrack);
3861
3926
  checkScreenShareVideoUnpublished();
3862
3927
  });
3928
+
3929
+ it('un-publishes the screen share audio track correctly', async () => {
3930
+ await meeting.unpublishTracks([audioShareTrack]);
3931
+
3932
+ assert.calledOnce(meeting.mediaProperties.webrtcMediaConnection.unpublishTrack);
3933
+ checkScreenShareAudioUnpublished();
3934
+ });
3935
+
3936
+ it('releases share floor and sets send direction to false when both screen share tracks are undefined', async () => {
3937
+ await meeting.unpublishTracks([videoShareTrack, audioShareTrack]);
3938
+
3939
+ assert.calledOnce(meeting.releaseScreenShareFloor);
3940
+ assert.equal(meeting.mediaProperties.mediaDirection.sendShare, false);
3941
+ });
3942
+
3943
+ it('does not release share floor when audio is released and video still exists', async () => {
3944
+ await meeting.unpublishTracks([audioShareTrack]);
3945
+ assert.notCalled(meeting.releaseScreenShareFloor);
3946
+ });
3947
+
3948
+ it('does not release share floor when video is released and audio still exists', async () => {
3949
+ await meeting.unpublishTracks([videoShareTrack]);
3950
+ assert.notCalled(meeting.releaseScreenShareFloor);
3951
+ });
3863
3952
  });
3864
3953
  });
3865
3954
  });
@@ -3912,7 +4001,8 @@ describe('plugin-meetings', () => {
3912
4001
  sandbox.stub(Media, 'stopTracks').returns(Promise.resolve());
3913
4002
  sandbox.stub(meeting.mediaProperties, 'audioTrack').value(fakeMediaTrack());
3914
4003
  sandbox.stub(meeting.mediaProperties, 'videoTrack').value(fakeMediaTrack());
3915
- sandbox.stub(meeting.mediaProperties, 'shareTrack').value(fakeMediaTrack());
4004
+ sandbox.stub(meeting.mediaProperties, 'shareVideoTrack').value(fakeMediaTrack());
4005
+ sandbox.stub(meeting.mediaProperties, 'shareAudioTrack').value(fakeMediaTrack());
3916
4006
  sandbox.stub(meeting.mediaProperties, 'remoteAudioTrack').value(fakeMediaTrack());
3917
4007
  sandbox.stub(meeting.mediaProperties, 'remoteVideoTrack').value(fakeMediaTrack());
3918
4008
  sandbox.stub(meeting.mediaProperties, 'remoteShare').value(fakeMediaTrack());
@@ -5083,6 +5173,7 @@ describe('plugin-meetings', () => {
5083
5173
  meeting.meetingRequest.changeMeetingFloor = sinon.stub().returns(Promise.resolve());
5084
5174
  });
5085
5175
  it('should call changeMeetingFloor()', async () => {
5176
+ meeting.screenShareFloorState = 'GRANTED';
5086
5177
  const share = meeting.releaseScreenShareFloor();
5087
5178
 
5088
5179
  assert.exists(share.then);
@@ -5,22 +5,21 @@ import MemberUtil from '@webex/plugin-meetings/src/member/util';
5
5
  import Member from '@webex/plugin-meetings/src/member';
6
6
 
7
7
  describe('member', () => {
8
+ const participant = {controls: {}, status: {}};
9
+
10
+ const member = new Member(participant);
11
+
8
12
  afterEach(() => {
9
13
  sinon.restore();
10
14
  });
11
15
 
12
16
  it('checks member properties', () => {
13
- const member = new Member({});
14
17
  assert.exists(member.supportsInterpretation);
15
18
  assert.exists(member.supportsBreakouts);
16
19
  assert.exists(member.supportLiveAnnotation);
17
20
  });
18
21
 
19
22
  it('checks that processParticipant calls isHandRaised', () => {
20
- const participant = {controls: {}};
21
-
22
- const member = new Member({});
23
-
24
23
  sinon.spy(MemberUtil, 'isHandRaised');
25
24
  member.processParticipant(participant);
26
25
 
@@ -29,10 +28,6 @@ describe('member', () => {
29
28
 
30
29
  describe('roles', () => {
31
30
  it('checks that processParticipant calls processRoles', () => {
32
- const participant = {};
33
-
34
- const member = new Member({});
35
-
36
31
  sinon.spy(member, 'processRoles');
37
32
  member.processParticipant(participant);
38
33
 
@@ -40,14 +35,42 @@ describe('member', () => {
40
35
  });
41
36
 
42
37
  it('checks that processRoles calls extractControlRoles', () => {
43
- const participant = {};
44
-
45
- const member = new Member({});
46
-
47
38
  sinon.spy(MemberUtil, 'extractControlRoles');
48
39
  member.processParticipant(participant);
49
40
 
50
41
  assert.calledOnceWithExactly(MemberUtil.extractControlRoles, participant);
51
42
  });
43
+ });
44
+
45
+ describe('#processParticipant', () => {
46
+ it('checks that processParticipant calls isHandRaised', () => {
47
+ sinon.spy(MemberUtil, 'isHandRaised');
48
+ member.processParticipant(participant);
49
+
50
+ assert.calledOnceWithExactly(MemberUtil.isHandRaised, participant);
51
+ });
52
+ })
53
+
54
+ describe('#processMember', () => {
55
+ it('checks that processMember calls isRemovable', () => {
56
+ sinon.spy(MemberUtil, 'isRemovable');
57
+ member.processMember();
58
+
59
+ assert.calledOnce(MemberUtil.isRemovable);
60
+ });
61
+
62
+ it('checks that processMember calls isMutable', () => {
63
+ sinon.spy(MemberUtil, 'isMutable');
64
+ member.processMember();
65
+
66
+ assert.calledOnce(MemberUtil.isMutable);
67
+ });
68
+
69
+ it('checks that processMember calls extractMediaStatus', () => {
70
+ sinon.spy(MemberUtil, 'extractMediaStatus');
71
+ member.processMember();
72
+
73
+ assert.calledOnceWithExactly(MemberUtil.extractMediaStatus, participant);
74
+ });
52
75
  })
53
76
  });
@@ -423,3 +423,34 @@ describe('plugin-meetings', () => {
423
423
  });
424
424
  });
425
425
  });
426
+
427
+ describe('extractMediaStatus', () => {
428
+ it('throws error when there is no participant', () => {
429
+ assert.throws(() => {
430
+ MemberUtil.extractMediaStatus()
431
+ }, 'Media status could not be extracted, participant is undefined.');
432
+ });
433
+
434
+ it('returns undefined media status when participant audio/video status is not present', () => {
435
+ const participant = {
436
+ status: {}
437
+ };
438
+
439
+ const mediaStatus = MemberUtil.extractMediaStatus(participant)
440
+
441
+ assert.deepEqual(mediaStatus, {audio: undefined, video: undefined});
442
+ });
443
+
444
+ it('returns correct media status when participant audio/video status is present', () => {
445
+ const participant = {
446
+ status: {
447
+ audioStatus: 'RECVONLY',
448
+ videoStatus: 'SENDRECV'
449
+ }
450
+ };
451
+
452
+ const mediaStatus = MemberUtil.extractMediaStatus(participant)
453
+
454
+ assert.deepEqual(mediaStatus, {audio: 'RECVONLY', video: 'SENDRECV'});
455
+ });
456
+ });