@webex/plugin-meetings 3.0.0-beta.167 → 3.0.0-beta.169

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.
@@ -1,5 +1,5 @@
1
1
  import Meetings from './meetings';
2
- export { getDevices, LocalTrack, LocalDisplayTrack, LocalTrackEvents, type TrackMuteEvent, type ServerMuteReason, LocalMicrophoneTrackEvents, LocalCameraTrackEvents, LocalMicrophoneTrack, LocalCameraTrack, createMicrophoneTrack, createCameraTrack, createDisplayTrack, } from '@webex/media-helpers';
2
+ export { getDevices, LocalTrack, LocalDisplayTrack, LocalTrackEvents, type TrackMuteEvent, type ServerMuteReason, LocalMicrophoneTrackEvents, LocalCameraTrackEvents, LocalMicrophoneTrack, LocalCameraTrack, createMicrophoneTrack, createCameraTrack, createDisplayTrack, FacingMode, DisplaySurface, PresetCameraConstraints, } from '@webex/media-helpers';
3
3
  export default Meetings;
4
4
  export * as CONSTANTS from './constants';
5
5
  export * as REACTIONS from './reactions/reactions';
@@ -36,6 +36,7 @@ export type AddMediaOptions = {
36
36
  receiveShare?: boolean;
37
37
  remoteMediaManagerConfig?: RemoteMediaManagerConfiguration;
38
38
  bundlePolicy?: BundlePolicy;
39
+ allowMediaInLobby?: boolean;
39
40
  };
40
41
  export declare const MEDIA_UPDATE_TYPE: {
41
42
  TRANSCODED_MEDIA_CONNECTION: string;
@@ -875,7 +876,7 @@ export default class Meeting extends StatelessWebexPlugin {
875
876
  * Shorthand function to join AND set up media
876
877
  * @param {Object} options - options to join with media
877
878
  * @param {JoinOptions} [options.joinOptions] - see #join()
878
- * @param {MediaDirection} [options.mediaOptions] - see #addMedia()
879
+ * @param {AddMediaOptions} [options.mediaOptions] - see #addMedia()
879
880
  * @returns {Promise} -- {join: see join(), media: see addMedia()}
880
881
  * @public
881
882
  * @memberof Meeting
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/plugin-meetings",
3
- "version": "3.0.0-beta.167",
3
+ "version": "3.0.0-beta.169",
4
4
  "description": "",
5
5
  "license": "Cisco EULA (https://www.cisco.com/c/en/us/products/end-user-license-agreement.html)",
6
6
  "contributors": [
@@ -32,12 +32,12 @@
32
32
  "build": "yarn run -T tsc --declaration true --declarationDir ./dist/types"
33
33
  },
34
34
  "devDependencies": {
35
- "@webex/plugin-meetings": "3.0.0-beta.167",
36
- "@webex/test-helper-chai": "3.0.0-beta.167",
37
- "@webex/test-helper-mocha": "3.0.0-beta.167",
38
- "@webex/test-helper-mock-webex": "3.0.0-beta.167",
39
- "@webex/test-helper-retry": "3.0.0-beta.167",
40
- "@webex/test-helper-test-users": "3.0.0-beta.167",
35
+ "@webex/plugin-meetings": "3.0.0-beta.169",
36
+ "@webex/test-helper-chai": "3.0.0-beta.169",
37
+ "@webex/test-helper-mocha": "3.0.0-beta.169",
38
+ "@webex/test-helper-mock-webex": "3.0.0-beta.169",
39
+ "@webex/test-helper-retry": "3.0.0-beta.169",
40
+ "@webex/test-helper-test-users": "3.0.0-beta.169",
41
41
  "chai": "^4.3.4",
42
42
  "chai-as-promised": "^7.1.1",
43
43
  "jsdom-global": "3.0.2",
@@ -46,19 +46,19 @@
46
46
  "typescript": "^4.7.4"
47
47
  },
48
48
  "dependencies": {
49
- "@webex/common": "3.0.0-beta.167",
49
+ "@webex/common": "3.0.0-beta.169",
50
50
  "@webex/internal-media-core": "1.38.6",
51
- "@webex/internal-plugin-conversation": "3.0.0-beta.167",
52
- "@webex/internal-plugin-device": "3.0.0-beta.167",
53
- "@webex/internal-plugin-llm": "3.0.0-beta.167",
54
- "@webex/internal-plugin-mercury": "3.0.0-beta.167",
55
- "@webex/internal-plugin-metrics": "3.0.0-beta.167",
56
- "@webex/internal-plugin-support": "3.0.0-beta.167",
57
- "@webex/internal-plugin-user": "3.0.0-beta.167",
58
- "@webex/media-helpers": "3.0.0-beta.167",
59
- "@webex/plugin-people": "3.0.0-beta.167",
60
- "@webex/plugin-rooms": "3.0.0-beta.167",
61
- "@webex/webex-core": "3.0.0-beta.167",
51
+ "@webex/internal-plugin-conversation": "3.0.0-beta.169",
52
+ "@webex/internal-plugin-device": "3.0.0-beta.169",
53
+ "@webex/internal-plugin-llm": "3.0.0-beta.169",
54
+ "@webex/internal-plugin-mercury": "3.0.0-beta.169",
55
+ "@webex/internal-plugin-metrics": "3.0.0-beta.169",
56
+ "@webex/internal-plugin-support": "3.0.0-beta.169",
57
+ "@webex/internal-plugin-user": "3.0.0-beta.169",
58
+ "@webex/media-helpers": "3.0.0-beta.169",
59
+ "@webex/plugin-people": "3.0.0-beta.169",
60
+ "@webex/plugin-rooms": "3.0.0-beta.169",
61
+ "@webex/webex-core": "3.0.0-beta.169",
62
62
  "ampersand-collection": "^2.0.2",
63
63
  "bowser": "^2.11.0",
64
64
  "btoa": "^1.2.1",
@@ -68,7 +68,7 @@ const Breakout = WebexPlugin.extend({
68
68
  breakoutEvent.onBreakoutMoveRequest(
69
69
  {currentSession: this, meeting, breakoutMoveId},
70
70
  // @ts-ignore
71
- this.webex.internal.newMetrics.submitClientEvent
71
+ this.webex.internal.newMetrics.submitClientEvent.bind(this.webex.internal.newMetrics)
72
72
  );
73
73
  const result = await this.request({
74
74
  method: HTTP_VERBS.POST,
@@ -83,7 +83,7 @@ const Breakout = WebexPlugin.extend({
83
83
  breakoutEvent.onBreakoutMoveResponse(
84
84
  {currentSession: this, meeting, breakoutMoveId},
85
85
  // @ts-ignore
86
- this.webex.internal.newMetrics.submitClientEvent
86
+ this.webex.internal.newMetrics.submitClientEvent.bind(this.webex.internal.newMetrics)
87
87
  );
88
88
 
89
89
  return result;
@@ -356,7 +356,7 @@ const Breakouts = WebexPlugin.extend({
356
356
  breakoutMoveId: params.breakoutMoveId,
357
357
  },
358
358
  // @ts-ignore
359
- this.webex.internal.newMetrics.submitClientEvent
359
+ this.webex.internal.newMetrics.submitClientEvent.bind(this.webex.internal.newMetrics)
360
360
  );
361
361
  }
362
362
  },
package/src/index.ts CHANGED
@@ -22,6 +22,9 @@ export {
22
22
  createMicrophoneTrack,
23
23
  createCameraTrack,
24
24
  createDisplayTrack,
25
+ FacingMode,
26
+ DisplaySurface,
27
+ PresetCameraConstraints,
25
28
  } from '@webex/media-helpers';
26
29
 
27
30
  export default Meetings;
@@ -157,6 +157,7 @@ export type AddMediaOptions = {
157
157
  receiveShare?: boolean; // if not specified, default value true is used
158
158
  remoteMediaManagerConfig?: RemoteMediaManagerConfiguration; // applies only to multistream meetings
159
159
  bundlePolicy?: BundlePolicy; // applies only to multistream meetings
160
+ allowMediaInLobby?: boolean; // allows adding media when in the lobby
160
161
  };
161
162
 
162
163
  export const MEDIA_UPDATE_TYPE = {
@@ -3698,7 +3699,7 @@ export default class Meeting extends StatelessWebexPlugin {
3698
3699
  * Shorthand function to join AND set up media
3699
3700
  * @param {Object} options - options to join with media
3700
3701
  * @param {JoinOptions} [options.joinOptions] - see #join()
3701
- * @param {MediaDirection} [options.mediaOptions] - see #addMedia()
3702
+ * @param {AddMediaOptions} [options.mediaOptions] - see #addMedia()
3702
3703
  * @returns {Promise} -- {join: see join(), media: see addMedia()}
3703
3704
  * @public
3704
3705
  * @memberof Meeting
@@ -5133,11 +5134,6 @@ export default class Meeting extends StatelessWebexPlugin {
5133
5134
  if (MeetingUtil.isUserInLeftState(this.locusInfo)) {
5134
5135
  return Promise.reject(new UserNotJoinedError());
5135
5136
  }
5136
- // If the user is unjoined or guest waiting in lobby dont allow the user to addMedia
5137
- // @ts-ignore - isUserUnadmitted coming from SelfUtil
5138
- if (this.isUserUnadmitted && !this.wirelessShare) {
5139
- return Promise.reject(new UserInLobbyError());
5140
- }
5141
5137
 
5142
5138
  const {
5143
5139
  localTracks,
@@ -5146,8 +5142,15 @@ export default class Meeting extends StatelessWebexPlugin {
5146
5142
  receiveShare = true,
5147
5143
  remoteMediaManagerConfig,
5148
5144
  bundlePolicy,
5145
+ allowMediaInLobby,
5149
5146
  } = options;
5150
5147
 
5148
+ // If the user is unjoined or guest waiting in lobby dont allow the user to addMedia
5149
+ // @ts-ignore - isUserUnadmitted coming from SelfUtil
5150
+ if (this.isUserUnadmitted && !this.wirelessShare && !allowMediaInLobby) {
5151
+ return Promise.reject(new UserInLobbyError());
5152
+ }
5153
+
5151
5154
  // @ts-ignore
5152
5155
  this.webex.internal.newMetrics.submitClientEvent({
5153
5156
  name: 'client.media.capabilities',
@@ -89,6 +89,8 @@ describe('plugin-meetings', () => {
89
89
  })
90
90
  };
91
91
 
92
+ sinon.stub(webex.internal.newMetrics.submitClientEvent, 'bind').returns(webex.internal.newMetrics.submitClientEvent);
93
+
92
94
  let onBreakoutMoveRequestStub = sinon.stub(breakoutEvent, 'onBreakoutMoveRequest');
93
95
  let onBreakoutMoveResponseStub = sinon.stub(breakoutEvent, 'onBreakoutMoveResponse');
94
96
  await breakout.join();
@@ -49,6 +49,8 @@ describe('plugin-meetings', () => {
49
49
  it('send metric as expected', () => {
50
50
  const submitClientEvent = sinon.stub();
51
51
 
52
+ sinon.stub(submitClientEvent, 'bind').returns(webex.internal.newMetrics.submitClientEvent);
53
+
52
54
  breakoutEvent.postMoveCallAnalyzer = sinon.stub();
53
55
  const eventInfo = {newSession, mockMeeting, breakoutMoveId};
54
56
  breakoutEvent.onBreakoutMoveRequest(eventInfo, submitClientEvent);
@@ -61,6 +63,8 @@ describe('plugin-meetings', () => {
61
63
  it('send metric as expected', () => {
62
64
  const submitClientEvent = sinon.stub();
63
65
 
66
+ sinon.stub(submitClientEvent, 'bind').returns(webex.internal.newMetrics.submitClientEvent);
67
+
64
68
  breakoutEvent.postMoveCallAnalyzer = sinon.stub();
65
69
  const eventInfo = {newSession, mockMeeting, breakoutMoveId};
66
70
  breakoutEvent.onBreakoutMoveResponse(eventInfo, submitClientEvent);
@@ -72,6 +76,8 @@ describe('plugin-meetings', () => {
72
76
  it('send metric as expected', () => {
73
77
  const submitClientEvent = sinon.stub();
74
78
 
79
+ sinon.stub(submitClientEvent, 'bind').returns(webex.internal.newMetrics.submitClientEvent);
80
+
75
81
  breakoutEvent.postMoveCallAnalyzer = sinon.stub();
76
82
  const eventInfo = {newSession, mockMeeting, breakoutMoveId};
77
83
  breakoutEvent.onBreakoutJoinResponse(eventInfo, submitClientEvent);
@@ -484,19 +484,29 @@ describe('plugin-meetings', () => {
484
484
  });
485
485
 
486
486
  describe('#joinWithMedia', () => {
487
+
487
488
  it('should have #joinWithMedia', () => {
488
489
  assert.exists(meeting.joinWithMedia);
489
490
  });
491
+
490
492
  describe('resolution', () => {
491
493
  it('should success and return a promise', async () => {
492
494
  meeting.join = sinon.stub().returns(Promise.resolve(test1));
493
495
  meeting.addMedia = sinon.stub().returns(Promise.resolve(test4));
494
- const result = await meeting.joinWithMedia({});
495
- assert.calledOnce(meeting.join);
496
- assert.calledOnce(meeting.addMedia);
496
+
497
+ const joinOptions = {correlationId: '12345'};
498
+ const mediaOptions = {audioEnabled: test1, allowMediaInLobby: true};
499
+
500
+ const result = await meeting.joinWithMedia({
501
+ joinOptions,
502
+ mediaOptions,
503
+ });
504
+ assert.calledOnceWithExactly(meeting.join, joinOptions);
505
+ assert.calledOnceWithExactly(meeting.addMedia, mediaOptions);
497
506
  assert.deepEqual(result, {join: test1, media: test4});
498
507
  });
499
508
  });
509
+
500
510
  describe('rejection', () => {
501
511
  it('should error out and return a promise', async () => {
502
512
  meeting.join = sinon.stub().returns(Promise.reject());
@@ -821,6 +831,7 @@ describe('plugin-meetings', () => {
821
831
  });
822
832
  });
823
833
  });
834
+
824
835
  describe('#addMedia', () => {
825
836
  const muteStateStub = {
826
837
  handleClientRequest: sinon.stub().returns(Promise.resolve(true)),
@@ -1106,18 +1117,7 @@ describe('plugin-meetings', () => {
1106
1117
  });
1107
1118
  });
1108
1119
 
1109
- it('should attach the media and return promise', async () => {
1110
- meeting.roap.doTurnDiscovery = sinon
1111
- .stub()
1112
- .resolves({turnServerInfo: undefined, turnDiscoverySkippedReason: undefined});
1113
-
1114
- meeting.meetingState = 'ACTIVE';
1115
- const media = meeting.addMedia({
1116
- mediaSettings: {},
1117
- });
1118
-
1119
- assert.exists(media);
1120
- await media;
1120
+ const checkWorking = () => {
1121
1121
  assert.calledOnce(meeting.roap.doTurnDiscovery);
1122
1122
  assert.calledWith(meeting.roap.doTurnDiscovery, meeting, false);
1123
1123
  assert.calledOnce(meeting.mediaProperties.setMediaDirection);
@@ -1130,9 +1130,40 @@ describe('plugin-meetings', () => {
1130
1130
  );
1131
1131
  assert.calledOnce(meeting.setMercuryListener);
1132
1132
  assert.calledOnce(fakeMediaConnection.initiateOffer);
1133
- /* statsAnalyzer is initiated inside of addMedia so there isn't
1134
- * a good way to mock it without mocking the constructor
1135
- */
1133
+ }
1134
+
1135
+ it('should attach the media and return promise', async () => {
1136
+ meeting.roap.doTurnDiscovery = sinon
1137
+ .stub()
1138
+ .resolves({turnServerInfo: undefined, turnDiscoverySkippedReason: undefined});
1139
+
1140
+ meeting.meetingState = 'ACTIVE';
1141
+ const media = meeting.addMedia({
1142
+ mediaSettings: {},
1143
+ });
1144
+
1145
+ assert.exists(media);
1146
+ await media;
1147
+
1148
+ checkWorking();
1149
+ });
1150
+
1151
+ it('should attach the media and return promise when in the lobby if allowMediaInLobby is set', async () => {
1152
+ meeting.roap.doTurnDiscovery = sinon
1153
+ .stub()
1154
+ .resolves({turnServerInfo: undefined, turnDiscoverySkippedReason: undefined});
1155
+
1156
+ meeting.meetingState = 'ACTIVE';
1157
+ meeting.locusInfo.parsedLocus = {self: {state: 'IDLE'}};
1158
+ meeting.isUserUnadmitted = true;
1159
+ const media = meeting.addMedia({
1160
+ allowMediaInLobby: true,
1161
+ });
1162
+
1163
+ assert.exists(media);
1164
+ await media;
1165
+
1166
+ checkWorking();
1136
1167
  });
1137
1168
 
1138
1169
  it('should pass the turn server info to the peer connection', async () => {