@webex/plugin-meetings 3.0.0-beta.261 → 3.0.0-beta.262

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/plugin-meetings",
3
- "version": "3.0.0-beta.261",
3
+ "version": "3.0.0-beta.262",
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.261",
36
- "@webex/test-helper-chai": "3.0.0-beta.261",
37
- "@webex/test-helper-mocha": "3.0.0-beta.261",
38
- "@webex/test-helper-mock-webex": "3.0.0-beta.261",
39
- "@webex/test-helper-retry": "3.0.0-beta.261",
40
- "@webex/test-helper-test-users": "3.0.0-beta.261",
35
+ "@webex/plugin-meetings": "3.0.0-beta.262",
36
+ "@webex/test-helper-chai": "3.0.0-beta.262",
37
+ "@webex/test-helper-mocha": "3.0.0-beta.262",
38
+ "@webex/test-helper-mock-webex": "3.0.0-beta.262",
39
+ "@webex/test-helper-retry": "3.0.0-beta.262",
40
+ "@webex/test-helper-test-users": "3.0.0-beta.262",
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.261",
49
+ "@webex/common": "3.0.0-beta.262",
50
50
  "@webex/internal-media-core": "2.0.4",
51
- "@webex/internal-plugin-conversation": "3.0.0-beta.261",
52
- "@webex/internal-plugin-device": "3.0.0-beta.261",
53
- "@webex/internal-plugin-llm": "3.0.0-beta.261",
54
- "@webex/internal-plugin-mercury": "3.0.0-beta.261",
55
- "@webex/internal-plugin-metrics": "3.0.0-beta.261",
56
- "@webex/internal-plugin-support": "3.0.0-beta.261",
57
- "@webex/internal-plugin-user": "3.0.0-beta.261",
58
- "@webex/media-helpers": "3.0.0-beta.261",
59
- "@webex/plugin-people": "3.0.0-beta.261",
60
- "@webex/plugin-rooms": "3.0.0-beta.261",
61
- "@webex/webex-core": "3.0.0-beta.261",
51
+ "@webex/internal-plugin-conversation": "3.0.0-beta.262",
52
+ "@webex/internal-plugin-device": "3.0.0-beta.262",
53
+ "@webex/internal-plugin-llm": "3.0.0-beta.262",
54
+ "@webex/internal-plugin-mercury": "3.0.0-beta.262",
55
+ "@webex/internal-plugin-metrics": "3.0.0-beta.262",
56
+ "@webex/internal-plugin-support": "3.0.0-beta.262",
57
+ "@webex/internal-plugin-user": "3.0.0-beta.262",
58
+ "@webex/media-helpers": "3.0.0-beta.262",
59
+ "@webex/plugin-people": "3.0.0-beta.262",
60
+ "@webex/plugin-rooms": "3.0.0-beta.262",
61
+ "@webex/webex-core": "3.0.0-beta.262",
62
62
  "ampersand-collection": "^2.0.2",
63
63
  "bowser": "^2.11.0",
64
64
  "btoa": "^1.2.1",
@@ -0,0 +1,24 @@
1
+ import {ERROR_DICTIONARY} from '../../constants';
2
+
3
+ /**
4
+ * Extended Error object for general parameter errors
5
+ */
6
+ export default class NoMeetingInfoError extends Error {
7
+ code: any;
8
+ error: any;
9
+ sdkMessage: any;
10
+
11
+ /**
12
+ * @constructor
13
+ * @param {String} [message]
14
+ * @param {Object} [error]
15
+ */
16
+ constructor(message: string = ERROR_DICTIONARY.NO_MEETING_INFO.MESSAGE, error: any = null) {
17
+ super(message);
18
+ this.name = ERROR_DICTIONARY.NO_MEETING_INFO.NAME;
19
+ this.sdkMessage = ERROR_DICTIONARY.NO_MEETING_INFO.MESSAGE;
20
+ this.error = error;
21
+ this.stack = error ? error.stack : new Error().stack;
22
+ this.code = ERROR_DICTIONARY.NO_MEETING_INFO.CODE;
23
+ }
24
+ }
package/src/constants.ts CHANGED
@@ -389,6 +389,7 @@ export const MEETING_REMOVED_REASON = {
389
389
  NO_MEETINGS_TO_SYNC: 'NO_MEETINGS_TO_SYNC', // After the syncMeeting no meeting exists
390
390
  MEETING_CONNECTION_FAILED: 'MEETING_CONNECTION_FAILED', // meeting failed to connect due to ice failures or firewall issue
391
391
  LOCUS_DTO_SYNC_FAILED: 'LOCUS_DTO_SYNC_FAILED', // failed to get any Locus DTO for that meeting
392
+ MISSING_MEETING_INFO: 'MISSING_MEETING_INFO', // meeting info failed to be fetched
392
393
  };
393
394
 
394
395
  // One one one calls ends for the following reasons
@@ -485,6 +486,11 @@ export const ERROR_DICTIONARY = {
485
486
  MESSAGE: 'Edit lock token mismatch',
486
487
  CODE: 9,
487
488
  },
489
+ NO_MEETING_INFO: {
490
+ NAME: 'NoMeetingInfo',
491
+ MESSAGE: 'No meeting info found for the meeting',
492
+ CODE: 10,
493
+ },
488
494
  };
489
495
 
490
496
  export const FLOOR_ACTION = {
@@ -61,6 +61,7 @@ import MeetingsUtil from './util';
61
61
  import PermissionError from '../common/errors/permission';
62
62
  import {INoiseReductionEffect, IVirtualBackgroundEffect} from './meetings.types';
63
63
  import {SpaceIDDeprecatedError} from '../common/errors/webex-errors';
64
+ import NoMeetingInfoError from '../common/errors/no-meeting-info';
64
65
 
65
66
  let mediaLogger;
66
67
 
@@ -1043,6 +1044,7 @@ export default class Meetings extends WebexPlugin {
1043
1044
  * @param {Boolean} useRandomDelayForInfo - whether a random delay should be added to fetching meeting info
1044
1045
  * @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
1045
1046
  * @param {string} correlationId - the optional specified correlationId
1047
+ * @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
1046
1048
  * @returns {Promise<Meeting>} A new Meeting.
1047
1049
  * @public
1048
1050
  * @memberof Meetings
@@ -1052,7 +1054,8 @@ export default class Meetings extends WebexPlugin {
1052
1054
  type: string = null,
1053
1055
  useRandomDelayForInfo = false,
1054
1056
  infoExtraParams = {},
1055
- correlationId: string = undefined
1057
+ correlationId: string = undefined,
1058
+ failOnMissingMeetingInfo = false
1056
1059
  ) {
1057
1060
  // TODO: type should be from a dictionary
1058
1061
 
@@ -1106,7 +1109,8 @@ export default class Meetings extends WebexPlugin {
1106
1109
  type,
1107
1110
  useRandomDelayForInfo,
1108
1111
  infoExtraParams,
1109
- correlationId
1112
+ correlationId,
1113
+ failOnMissingMeetingInfo
1110
1114
  ).then((createdMeeting: any) => {
1111
1115
  // If the meeting was successfully created.
1112
1116
  if (createdMeeting && createdMeeting.on) {
@@ -1161,6 +1165,7 @@ export default class Meetings extends WebexPlugin {
1161
1165
  * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
1162
1166
  * @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
1163
1167
  * @param {String} correlationId the optional specified correlationId
1168
+ * @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
1164
1169
  * @returns {Promise} a new meeting instance complete with meeting info and destination
1165
1170
  * @private
1166
1171
  * @memberof Meetings
@@ -1170,7 +1175,8 @@ export default class Meetings extends WebexPlugin {
1170
1175
  type: string = null,
1171
1176
  useRandomDelayForInfo = false,
1172
1177
  infoExtraParams = {},
1173
- correlationId: string = undefined
1178
+ correlationId: string = undefined,
1179
+ failOnMissingMeetingInfo = false
1174
1180
  ) {
1175
1181
  const meeting = new Meeting(
1176
1182
  {
@@ -1239,10 +1245,18 @@ export default class Meetings extends WebexPlugin {
1239
1245
  !(err instanceof PasswordError) &&
1240
1246
  !(err instanceof PermissionError)
1241
1247
  ) {
1242
- // if there is no meeting info we assume its a 1:1 call or wireless share
1243
1248
  LoggerProxy.logger.info(
1244
1249
  `Meetings:index#createMeeting --> Info Unable to fetch meeting info for ${destination}.`
1245
1250
  );
1251
+ if (failOnMissingMeetingInfo) {
1252
+ LoggerProxy.logger.info(
1253
+ `Meetings:index#createMeeting --> Destroying meeting due to missing meeting info.`
1254
+ );
1255
+ // @ts-ignore
1256
+ this.destroy(meeting, MEETING_REMOVED_REASON.MISSING_MEETING_INFO);
1257
+ throw new NoMeetingInfoError();
1258
+ }
1259
+ // if there is no meeting info and no error should be thrown then we assume its a 1:1 call or wireless share
1246
1260
  LoggerProxy.logger.info(
1247
1261
  'Meetings:index#createMeeting --> Info assuming this destination is a 1:1 or wireless share'
1248
1262
  );
@@ -36,6 +36,7 @@ import { forEach } from 'lodash';
36
36
  import PasswordError from '@webex/plugin-meetings/src/common/errors/password-error';
37
37
  import PermissionError from '@webex/plugin-meetings/src/common/errors/permission';
38
38
  import {NoiseReductionEffect,VirtualBackgroundEffect} from '@webex/media-helpers';
39
+ import NoMeetingInfoError from '../../../../src/common/errors/no-meeting-info';
39
40
 
40
41
  describe('plugin-meetings', () => {
41
42
  const logger = {
@@ -662,15 +663,28 @@ describe('plugin-meetings', () => {
662
663
  });
663
664
  });
664
665
 
665
- it('calls createMeeting and returns its promise', async () => {
666
- const FAKE_USE_RANDOM_DELAY = true;
667
- const correlationId = 'my-correlationId';
668
- const create = webex.meetings.create(test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId);
666
+ const FAKE_USE_RANDOM_DELAY = true;
667
+ const correlationId = 'my-correlationId';
668
+
669
+ const checkCallCreateMeeting = async (createParameters, createMeetingParameters) => {
670
+ const create = webex.meetings.create(...createParameters);
669
671
 
670
672
  assert.exists(create.then);
671
673
  await create;
672
674
  assert.calledOnce(webex.meetings.createMeeting);
673
- assert.calledWith(webex.meetings.createMeeting, test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId);
675
+ assert.calledWith(webex.meetings.createMeeting, ...createMeetingParameters);
676
+ }
677
+
678
+ it('calls createMeeting and returns its promise', async () => {
679
+ checkCallCreateMeeting([test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true], [test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true]);
680
+ });
681
+
682
+ it('calls createMeeting when failOnMissingMeetinginfo is undefined and returns its promise', async () => {
683
+ checkCallCreateMeeting([test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, undefined], [test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false]);
684
+ });
685
+
686
+ it('calls createMeeting when failOnMissingMeetinginfo is false and returns its promise', async () => {
687
+ checkCallCreateMeeting([test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false], [test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, false]);
674
688
  });
675
689
 
676
690
  it('calls createMeeting with extra info params and returns its promise', async () => {
@@ -1346,37 +1360,63 @@ describe('plugin-meetings', () => {
1346
1360
  webex.meetings.meetingInfo.fetchMeetingInfo = sinon
1347
1361
  .stub()
1348
1362
  .returns(Promise.reject(new Error('test')));
1363
+ webex.meetings.destroy = sinon
1364
+ .stub()
1365
+ .returns(Promise.resolve());
1366
+ webex.meetings.createMeeting = sinon.spy(webex.meetings.createMeeting);
1349
1367
  });
1350
- it('creates the meeting from a rejected meeting info fetch', async () => {
1351
- const meeting = await webex.meetings.createMeeting('test destination', 'test type');
1352
1368
 
1353
- assert.instanceOf(
1354
- meeting,
1355
- Meeting,
1356
- 'createMeeting should eventually resolve to a Meeting Object'
1357
- );
1358
- assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
1359
- assert.calledOnce(MeetingsUtil.getMeetingAddedType);
1360
- assert.calledThrice(TriggerProxy.trigger);
1361
- assert.calledWith(
1362
- webex.meetings.meetingInfo.fetchMeetingInfo,
1363
- 'test destination',
1364
- 'test type'
1365
- );
1366
- assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
1367
- assert.calledWith(
1368
- TriggerProxy.trigger,
1369
- sinon.match.instanceOf(Meetings),
1370
- {
1371
- file: 'meetings',
1372
- function: 'createMeeting',
1373
- },
1374
- 'meeting:added',
1375
- {
1376
- meeting: sinon.match.instanceOf(Meeting),
1377
- type: 'test meeting added type',
1369
+ const checkCreateMeetingWithNoMeetingInfo = async (failOnMissingMeetingInfo, destroy) => {
1370
+ try {
1371
+ const meeting = await webex.meetings.createMeeting('test destination', 'test type', undefined, undefined, undefined, failOnMissingMeetingInfo);
1372
+
1373
+ assert.instanceOf(
1374
+ meeting,
1375
+ Meeting,
1376
+ 'createMeeting should eventually resolve to a Meeting Object'
1377
+ );
1378
+ assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
1379
+ assert.calledOnce(MeetingsUtil.getMeetingAddedType);
1380
+ assert.calledThrice(TriggerProxy.trigger);
1381
+ assert.calledWith(
1382
+ webex.meetings.meetingInfo.fetchMeetingInfo,
1383
+ 'test destination',
1384
+ 'test type'
1385
+ );
1386
+
1387
+ if (destroy) {
1388
+ assert.calledWith(webex.meetings.destroy, sinon.match.instanceOf(Meeting), 'MISSING_MEETING_INFO')
1389
+ assert.notCalled(MeetingsUtil.getMeetingAddedType);
1390
+ assert.notCalled(TriggerProxy.trigger);
1391
+ assert.throw(webex.meetings.createMeeting, 'meeting information not found');
1392
+ } else {
1393
+ assert.notCalled(webex.meetings.destroy);
1394
+ assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
1395
+ assert.calledWith(
1396
+ TriggerProxy.trigger,
1397
+ sinon.match.instanceOf(Meetings),
1398
+ {
1399
+ file: 'meetings',
1400
+ function: 'createMeeting',
1401
+ },
1402
+ 'meeting:added',
1403
+ {
1404
+ meeting: sinon.match.instanceOf(Meeting),
1405
+ type: 'test meeting added type',
1406
+ }
1407
+ );
1378
1408
  }
1379
- );
1409
+ } catch (err) {
1410
+ assert.instanceOf(err, NoMeetingInfoError);
1411
+ }
1412
+ }
1413
+
1414
+ it('creates the meeting from a rejected meeting info fetch', async () => {
1415
+ checkCreateMeetingWithNoMeetingInfo(false, false);
1416
+ });
1417
+
1418
+ it('creates the meeting from a rejected meeting info fetch and destroys it if failOnMissingMeetingInfo', async () => {
1419
+ checkCreateMeetingWithNoMeetingInfo(true, true);
1380
1420
  });
1381
1421
  });
1382
1422