@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/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/common/errors/no-meeting-info.js +51 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/constants.js +8 -1
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/meetings/index.js +39 -21
- package/dist/meetings/index.js.map +1 -1
- package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/types/constants.d.ts +6 -0
- package/dist/types/meetings/index.d.ts +3 -1
- package/package.json +19 -19
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/constants.ts +6 -0
- package/src/meetings/index.ts +18 -4
- package/test/unit/spec/meetings/index.js +73 -33
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/plugin-meetings",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
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.
|
|
36
|
-
"@webex/test-helper-chai": "3.0.0-beta.
|
|
37
|
-
"@webex/test-helper-mocha": "3.0.0-beta.
|
|
38
|
-
"@webex/test-helper-mock-webex": "3.0.0-beta.
|
|
39
|
-
"@webex/test-helper-retry": "3.0.0-beta.
|
|
40
|
-
"@webex/test-helper-test-users": "3.0.0-beta.
|
|
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.
|
|
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.
|
|
52
|
-
"@webex/internal-plugin-device": "3.0.0-beta.
|
|
53
|
-
"@webex/internal-plugin-llm": "3.0.0-beta.
|
|
54
|
-
"@webex/internal-plugin-mercury": "3.0.0-beta.
|
|
55
|
-
"@webex/internal-plugin-metrics": "3.0.0-beta.
|
|
56
|
-
"@webex/internal-plugin-support": "3.0.0-beta.
|
|
57
|
-
"@webex/internal-plugin-user": "3.0.0-beta.
|
|
58
|
-
"@webex/media-helpers": "3.0.0-beta.
|
|
59
|
-
"@webex/plugin-people": "3.0.0-beta.
|
|
60
|
-
"@webex/plugin-rooms": "3.0.0-beta.
|
|
61
|
-
"@webex/webex-core": "3.0.0-beta.
|
|
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 = {
|
package/src/meetings/index.ts
CHANGED
|
@@ -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
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
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,
|
|
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
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
webex.meetings.meetingInfo.fetchMeetingInfo
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
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
|
|