@webex/plugin-meetings 3.0.0-beta.361 → 3.0.0-beta.363

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.
@@ -13,6 +13,7 @@ import {
13
13
  FULL_STATE,
14
14
  SELF_POLICY,
15
15
  EVENT_TRIGGERS,
16
+ LOCAL_SHARE_ERRORS,
16
17
  IP_VERSION,
17
18
  } from '../constants';
18
19
  import BrowserDetection from '../common/browser-detection';
@@ -692,6 +693,102 @@ const MeetingUtil = {
692
693
  EVENT_TRIGGERS.MEETING_INTERPRETATION_UPDATE
693
694
  );
694
695
  },
696
+
697
+ /**
698
+ * Returns a CA-recognized error payload for the specified raw error message/reason.
699
+ *
700
+ * New errors can be added to this function for handling in the future
701
+ *
702
+ * @param {String} reason the raw error message
703
+ * @returns {Array<object>} an array of payload objects
704
+ */
705
+ getChangeMeetingFloorErrorPayload: (reason: string) => {
706
+ const errorPayload = {
707
+ errorDescription: reason,
708
+ name: 'locus.response',
709
+ shownToUser: false,
710
+ };
711
+ if (reason.includes(LOCAL_SHARE_ERRORS.UNDEFINED)) {
712
+ return [
713
+ {
714
+ ...errorPayload,
715
+ fatal: true,
716
+ category: 'signaling',
717
+ errorCode: 1100,
718
+ },
719
+ ];
720
+ }
721
+ if (reason.includes(LOCAL_SHARE_ERRORS.DEVICE_NOT_JOINED)) {
722
+ return [
723
+ {
724
+ ...errorPayload,
725
+ fatal: true,
726
+ category: 'signaling',
727
+ errorCode: 4050,
728
+ },
729
+ ];
730
+ }
731
+ if (reason.includes(LOCAL_SHARE_ERRORS.NO_MEDIA_FOR_DEVICE)) {
732
+ return [
733
+ {
734
+ ...errorPayload,
735
+ fatal: true,
736
+ category: 'media',
737
+ errorCode: 2048,
738
+ },
739
+ ];
740
+ }
741
+ if (reason.includes(LOCAL_SHARE_ERRORS.NO_CONFLUENCE_ID)) {
742
+ return [
743
+ {
744
+ ...errorPayload,
745
+ fatal: true,
746
+ category: 'signaling',
747
+ errorCode: 4064,
748
+ },
749
+ ];
750
+ }
751
+ if (reason.includes(LOCAL_SHARE_ERRORS.CONTENT_SHARING_DISABLED)) {
752
+ return [
753
+ {
754
+ ...errorPayload,
755
+ fatal: true,
756
+ category: 'expected',
757
+ errorCode: 4065,
758
+ },
759
+ ];
760
+ }
761
+ if (reason.includes(LOCAL_SHARE_ERRORS.LOCUS_PARTICIPANT_DNE)) {
762
+ return [
763
+ {
764
+ ...errorPayload,
765
+ fatal: true,
766
+ category: 'signaling',
767
+ errorCode: 4066,
768
+ },
769
+ ];
770
+ }
771
+ if (reason.includes(LOCAL_SHARE_ERRORS.CONTENT_REQUEST_WHILE_PENDING_WHITEBOARD)) {
772
+ return [
773
+ {
774
+ ...errorPayload,
775
+ fatal: true,
776
+ category: 'expected',
777
+ errorCode: 4067,
778
+ },
779
+ ];
780
+ }
781
+
782
+ // return unknown error
783
+ return [
784
+ {
785
+ ...errorPayload,
786
+ fatal: true,
787
+ category: 'signaling',
788
+ errorCode: 1100,
789
+ },
790
+ ];
791
+ },
695
792
  };
696
793
 
697
794
  export default MeetingUtil;
@@ -3785,6 +3785,7 @@ describe('plugin-meetings', () => {
3785
3785
  it('should have #requestScreenShareFloor', () => {
3786
3786
  assert.exists(meeting.requestScreenShareFloor);
3787
3787
  });
3788
+
3788
3789
  beforeEach(() => {
3789
3790
  meeting.locusInfo.mediaShares = [{name: 'content', url: url1}];
3790
3791
  meeting.locusInfo.self = {url: url1};
@@ -3792,13 +3793,47 @@ describe('plugin-meetings', () => {
3792
3793
  meeting.mediaProperties.shareVideoStream = {};
3793
3794
  meeting.mediaProperties.mediaDirection.sendShare = true;
3794
3795
  meeting.state = 'JOINED';
3796
+ meeting.localShareInstanceId = '1234-5678';
3797
+ });
3798
+
3799
+ afterEach(() => {
3800
+ sinon.restore();
3795
3801
  });
3802
+
3796
3803
  it('should send the share', async () => {
3797
3804
  const share = meeting.requestScreenShareFloor();
3798
3805
 
3799
3806
  assert.exists(share.then);
3800
3807
  await share;
3801
3808
  assert.calledOnce(meeting.meetingRequest.changeMeetingFloor);
3809
+
3810
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
3811
+ name: 'client.share.floor-grant.request',
3812
+ payload: {mediaType: 'share', shareInstanceId: '1234-5678'},
3813
+ options: {meetingId: meeting.id},
3814
+ });
3815
+ });
3816
+
3817
+ it('should submit expected metric on failure', async () => {
3818
+ const error = new Error('forced');
3819
+
3820
+ meeting.meetingRequest.changeMeetingFloor = sinon.stub().returns(Promise.reject(error));
3821
+ const getChangeMeetingFloorErrorPayloadSpy = sinon
3822
+ .stub(MeetingUtil, 'getChangeMeetingFloorErrorPayload')
3823
+ .returns('foo');
3824
+
3825
+ await meeting.requestScreenShareFloor().catch((err) => {
3826
+ assert.equal(err, error);
3827
+ });
3828
+
3829
+ assert.calledWith(getChangeMeetingFloorErrorPayloadSpy, 'forced');
3830
+
3831
+ // ensure the expected CA share metric is submitted
3832
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
3833
+ name: 'client.share.floor-granted.local',
3834
+ payload: {mediaType: 'share', errors: 'foo', shareInstanceId: '1234-5678'},
3835
+ options: {meetingId: meeting.id},
3836
+ });
3802
3837
  });
3803
3838
  });
3804
3839
 
@@ -5776,16 +5811,22 @@ describe('plugin-meetings', () => {
5776
5811
  const checkScreenShareVideoPublished = (stream) => {
5777
5812
  assert.calledOnce(meeting.requestScreenShareFloor);
5778
5813
 
5779
- assert.calledWith(
5780
- meeting.sendSlotManager.getSlot(MediaType.VideoSlides).publishStream,
5781
- stream
5782
- );
5783
- assert.equal(meeting.mediaProperties.shareVideoStream, stream);
5814
+ // ensure the CA share metrics are submitted
5815
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
5816
+ name: 'client.share.initiated',
5817
+ payload: {mediaType: 'share', shareInstanceId: meeting.localShareInstanceId},
5818
+ options: {meetingId: meeting.id},
5819
+ });
5784
5820
  assert.equal(meeting.mediaProperties.mediaDirection.sendShare, true);
5785
5821
  };
5786
5822
 
5787
5823
  const checkScreenShareAudioPublished = (stream) => {
5788
- assert.calledOnce(meeting.requestScreenShareFloor);
5824
+ // ensure the CA share metrics are submitted
5825
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
5826
+ name: 'client.share.initiated',
5827
+ payload: {mediaType: 'share', shareInstanceId: meeting.localShareInstanceId},
5828
+ options: {meetingId: meeting.id},
5829
+ });
5789
5830
 
5790
5831
  assert.calledWith(
5791
5832
  meeting.sendSlotManager.getSlot(MediaType.AudioSlides).publishStream,
@@ -9008,6 +9049,13 @@ describe('plugin-meetings', () => {
9008
9049
  assert.exists(whiteboardShare.then);
9009
9050
  await whiteboardShare;
9010
9051
  assert.calledOnce(meeting.meetingRequest.changeMeetingFloor);
9052
+
9053
+ // ensure the CA share metric is submitted
9054
+ assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
9055
+ name: 'client.share.initiated',
9056
+ payload: {mediaType: 'whiteboard'},
9057
+ options: {meetingId: meeting.id},
9058
+ });
9011
9059
  });
9012
9060
  });
9013
9061
  describe('#stopWhiteboardShare', () => {
@@ -2,6 +2,7 @@ import sinon from 'sinon';
2
2
  import {assert} from '@webex/test-helper-chai';
3
3
  import Meetings from '@webex/plugin-meetings';
4
4
  import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
5
+ import {LOCAL_SHARE_ERRORS} from '@webex/plugin-meetings/src/constants';
5
6
  import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
6
7
  import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
7
8
  import {SELF_POLICY, IP_VERSION} from '@webex/plugin-meetings/src/constants';
@@ -1032,5 +1033,97 @@ describe('plugin-meetings', () => {
1032
1033
  });
1033
1034
  });
1034
1035
  });
1036
+
1037
+ describe('getChangeMeetingFloorErrorPayload', () => {
1038
+ [
1039
+ {
1040
+ reason: LOCAL_SHARE_ERRORS.UNDEFINED,
1041
+ expected: {
1042
+ category: 'signaling',
1043
+ errorCode: 1100,
1044
+ },
1045
+ },
1046
+ {
1047
+ reason: LOCAL_SHARE_ERRORS.DEVICE_NOT_JOINED,
1048
+ expected: {
1049
+ category: 'signaling',
1050
+ errorCode: 4050,
1051
+ },
1052
+ },
1053
+ {
1054
+ reason: LOCAL_SHARE_ERRORS.NO_MEDIA_FOR_DEVICE,
1055
+ expected: {
1056
+ category: 'media',
1057
+ errorCode: 2048,
1058
+ },
1059
+ },
1060
+ {
1061
+ reason: LOCAL_SHARE_ERRORS.NO_CONFLUENCE_ID,
1062
+ expected: {
1063
+ category: 'signaling',
1064
+ errorCode: 4064,
1065
+ },
1066
+ },
1067
+ {
1068
+ reason: LOCAL_SHARE_ERRORS.CONTENT_SHARING_DISABLED,
1069
+ expected: {
1070
+ category: 'expected',
1071
+ errorCode: 4065,
1072
+ },
1073
+ },
1074
+ {
1075
+ reason: LOCAL_SHARE_ERRORS.LOCUS_PARTICIPANT_DNE,
1076
+ expected: {
1077
+ category: 'signaling',
1078
+ errorCode: 4066,
1079
+ },
1080
+ },
1081
+ {
1082
+ reason: LOCAL_SHARE_ERRORS.CONTENT_REQUEST_WHILE_PENDING_WHITEBOARD,
1083
+ expected: {
1084
+ category: 'expected',
1085
+ errorCode: 4067,
1086
+ },
1087
+ },
1088
+ {
1089
+ reason: 'some unknown reason',
1090
+ expected: {
1091
+ category: 'signaling',
1092
+ errorCode: 1100,
1093
+ },
1094
+ },
1095
+ ].forEach(({reason, expected}) => {
1096
+ const expectedFull = {
1097
+ errorDescription: reason,
1098
+ name: 'locus.response',
1099
+ shownToUser: false,
1100
+ fatal: true,
1101
+ ...expected,
1102
+ };
1103
+ it(`returns expected when reason="${reason}"`, () => {
1104
+ const result = MeetingUtil.getChangeMeetingFloorErrorPayload(reason);
1105
+ assert.equal(result.length, 1);
1106
+
1107
+ const error = result[0];
1108
+ assert.deepEqual(error, expectedFull);
1109
+ });
1110
+ });
1111
+
1112
+ it('properly handles "includes"', () => {
1113
+ const reason = '>>> ' + LOCAL_SHARE_ERRORS.DEVICE_NOT_JOINED + ' <<<';
1114
+ const result = MeetingUtil.getChangeMeetingFloorErrorPayload(reason);
1115
+ assert.equal(result.length, 1);
1116
+
1117
+ const error = result[0];
1118
+ assert.deepEqual(error, {
1119
+ category: 'signaling',
1120
+ errorCode: 4050,
1121
+ errorDescription: reason,
1122
+ name: 'locus.response',
1123
+ shownToUser: false,
1124
+ fatal: true,
1125
+ });
1126
+ });
1127
+ });
1035
1128
  });
1036
1129
  });