@webex/plugin-meetings 3.5.0 → 3.6.0-next.10
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/webinar-registration-error.js +50 -0
- package/dist/common/errors/webinar-registration-error.js.map +1 -0
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +8 -0
- package/dist/constants.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/parser.js +5 -1
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/media/index.js +3 -1
- package/dist/media/index.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +3 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +185 -103
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/muteState.js +5 -2
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/util.js +8 -10
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +68 -17
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meetings/index.js +102 -27
- package/dist/meetings/index.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/remoteMedia.js +4 -0
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/roap/request.js +1 -1
- package/dist/roap/request.js.map +1 -1
- package/dist/types/common/errors/webinar-registration-error.d.ts +14 -0
- package/dist/types/config.d.ts +2 -0
- package/dist/types/constants.d.ts +8 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/meeting/in-meeting-actions.d.ts +2 -0
- package/dist/types/meeting/index.d.ts +11 -0
- package/dist/types/meeting/muteState.d.ts +2 -1
- package/dist/types/meeting-info/meeting-info-v2.d.ts +23 -0
- package/dist/types/meetings/index.d.ts +43 -2
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/multistream/remoteMedia.d.ts +1 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/common/errors/webinar-registration-error.ts +27 -0
- package/src/config.ts +3 -0
- package/src/constants.ts +7 -0
- package/src/index.ts +2 -0
- package/src/locus-info/parser.ts +8 -1
- package/src/media/index.ts +4 -1
- package/src/meeting/in-meeting-actions.ts +3 -0
- package/src/meeting/index.ts +82 -13
- package/src/meeting/muteState.ts +6 -2
- package/src/meeting/util.ts +27 -31
- package/src/meeting-info/meeting-info-v2.ts +51 -0
- package/src/meetings/index.ts +129 -38
- package/src/metrics/constants.ts +1 -0
- package/src/multistream/remoteMedia.ts +5 -0
- package/src/roap/request.ts +3 -1
- package/test/unit/spec/locus-info/index.js +29 -0
- package/test/unit/spec/media/index.ts +4 -0
- package/test/unit/spec/meeting/in-meeting-actions.ts +2 -0
- package/test/unit/spec/meeting/index.js +118 -18
- package/test/unit/spec/meeting/muteState.js +8 -4
- package/test/unit/spec/meeting/utils.js +50 -85
- package/test/unit/spec/meeting-info/meetinginfov2.js +37 -0
- package/test/unit/spec/meetings/index.js +128 -13
- package/test/unit/spec/multistream/remoteMedia.ts +16 -2
- package/dist/networkQualityMonitor/index.js +0 -227
- package/dist/networkQualityMonitor/index.js.map +0 -1
- package/dist/rtcMetrics/constants.js +0 -11
- package/dist/rtcMetrics/constants.js.map +0 -1
- package/dist/rtcMetrics/index.js +0 -197
- package/dist/rtcMetrics/index.js.map +0 -1
- package/dist/types/networkQualityMonitor/index.d.ts +0 -70
- package/dist/types/rtcMetrics/constants.d.ts +0 -4
- package/dist/types/rtcMetrics/index.d.ts +0 -71
- package/src/rtcMetrics/constants.ts +0 -3
- package/src/rtcMetrics/index.ts +0 -186
- package/test/unit/spec/rtcMetrics/index.ts +0 -154
package/src/meetings/index.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/* eslint no-shadow: ["error", { "allow": ["eventType"] }] */
|
|
2
|
-
import {
|
|
2
|
+
import {cloneDeep} from 'lodash';
|
|
3
3
|
import '@webex/internal-plugin-mercury';
|
|
4
4
|
import '@webex/internal-plugin-conversation';
|
|
5
5
|
import '@webex/internal-plugin-metrics';
|
|
6
6
|
// @ts-ignore
|
|
7
7
|
import {WebexPlugin} from '@webex/webex-core';
|
|
8
8
|
import {setLogger} from '@webex/internal-media-core';
|
|
9
|
+
import {DeviceRegistrationOptions} from '@webex/internal-plugin-device';
|
|
9
10
|
|
|
10
11
|
import * as mediaHelpersModule from '@webex/media-helpers';
|
|
11
12
|
|
|
@@ -55,6 +56,7 @@ import MeetingCollection from './collection';
|
|
|
55
56
|
import {MEETING_KEY, INoiseReductionEffect, IVirtualBackgroundEffect} from './meetings.types';
|
|
56
57
|
import MeetingsUtil from './util';
|
|
57
58
|
import PermissionError from '../common/errors/permission';
|
|
59
|
+
import WebinarRegistrationError from '../common/errors/webinar-registration-error';
|
|
58
60
|
import {SpaceIDDeprecatedError} from '../common/errors/webex-errors';
|
|
59
61
|
import NoMeetingInfoError from '../common/errors/no-meeting-info';
|
|
60
62
|
|
|
@@ -133,6 +135,28 @@ class MediaLogger {
|
|
|
133
135
|
* @memberof Meetings
|
|
134
136
|
*/
|
|
135
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Object containing only the most basic information about a meeting.
|
|
140
|
+
* This is the information that is kept even after the meeting is deleted from the MeetingCollection
|
|
141
|
+
*/
|
|
142
|
+
export type BasicMeetingInformation = {
|
|
143
|
+
allowMediaInLobby: boolean;
|
|
144
|
+
correlationId: string;
|
|
145
|
+
environment: string;
|
|
146
|
+
id: string;
|
|
147
|
+
locusUrl: string;
|
|
148
|
+
locusInfo: {
|
|
149
|
+
// it's only a very small subset of the locus info, to avoid using much memory
|
|
150
|
+
url: string;
|
|
151
|
+
fullState: {
|
|
152
|
+
lastActive: string;
|
|
153
|
+
sessionId: string;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
meetingInfo: any;
|
|
157
|
+
sessionCorrelationId: string;
|
|
158
|
+
};
|
|
159
|
+
|
|
136
160
|
/**
|
|
137
161
|
* Maintain a cache of meetings and sync with services.
|
|
138
162
|
* @class
|
|
@@ -141,6 +165,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
141
165
|
loggerRequest: any;
|
|
142
166
|
media: any;
|
|
143
167
|
meetingCollection: any;
|
|
168
|
+
deletedMeetings: Map<string, BasicMeetingInformation>;
|
|
144
169
|
personalMeetingRoom: any;
|
|
145
170
|
preferredWebexSite: any;
|
|
146
171
|
reachability: Reachability;
|
|
@@ -191,6 +216,8 @@ export default class Meetings extends WebexPlugin {
|
|
|
191
216
|
// @ts-ignore
|
|
192
217
|
this.loggerRequest = new LoggerRequest({webex: this.webex});
|
|
193
218
|
this.meetingCollection = new MeetingCollection();
|
|
219
|
+
this.deletedMeetings = new Map();
|
|
220
|
+
|
|
194
221
|
/**
|
|
195
222
|
* The PersonalMeetingRoom object to interact with server
|
|
196
223
|
* @instance
|
|
@@ -736,15 +763,35 @@ export default class Meetings extends WebexPlugin {
|
|
|
736
763
|
}
|
|
737
764
|
}
|
|
738
765
|
|
|
766
|
+
/**
|
|
767
|
+
* API to toggle backend ipv6 native support config, needs to be called before webex.meetings.register()
|
|
768
|
+
*
|
|
769
|
+
* @param {Boolean} newValue
|
|
770
|
+
* @private
|
|
771
|
+
* @memberof Meetings
|
|
772
|
+
* @returns {undefined}
|
|
773
|
+
*/
|
|
774
|
+
private _toggleIpv6BackendNativeSupport(newValue: boolean) {
|
|
775
|
+
if (typeof newValue !== 'boolean') {
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
// @ts-ignore
|
|
779
|
+
if (this.config.backendIpv6NativeSupport !== newValue) {
|
|
780
|
+
// @ts-ignore
|
|
781
|
+
this.config.backendIpv6NativeSupport = newValue;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
|
|
739
785
|
/**
|
|
740
786
|
* Explicitly sets up the meetings plugin by registering
|
|
741
787
|
* the device, connecting to mercury, and listening for locus events.
|
|
742
788
|
*
|
|
789
|
+
* @param {DeviceRegistrationOptions} [deviceRegistrationOptions] - The options for registering the device (optional)
|
|
743
790
|
* @returns {Promise}
|
|
744
791
|
* @public
|
|
745
792
|
* @memberof Meetings
|
|
746
793
|
*/
|
|
747
|
-
public register() {
|
|
794
|
+
public register(deviceRegistrationOptions?: DeviceRegistrationOptions): Promise<any> {
|
|
748
795
|
// @ts-ignore
|
|
749
796
|
if (!this.webex.canAuthorize) {
|
|
750
797
|
LoggerProxy.logger.error(
|
|
@@ -770,7 +817,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
770
817
|
}),
|
|
771
818
|
// @ts-ignore
|
|
772
819
|
this.webex.internal.device
|
|
773
|
-
.register()
|
|
820
|
+
.register(deviceRegistrationOptions)
|
|
774
821
|
// @ts-ignore
|
|
775
822
|
.then(() =>
|
|
776
823
|
LoggerProxy.logger.info(
|
|
@@ -996,35 +1043,45 @@ export default class Meetings extends WebexPlugin {
|
|
|
996
1043
|
* @memberof Meetings
|
|
997
1044
|
*/
|
|
998
1045
|
fetchUserPreferredWebexSite() {
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1046
|
+
// @ts-ignore
|
|
1047
|
+
return this.webex.people._getMe().then((me) => {
|
|
1048
|
+
const isGuestUser = me.type === 'appuser';
|
|
1049
|
+
if (!isGuestUser) {
|
|
1050
|
+
return this.request.getMeetingPreferences().then((res) => {
|
|
1051
|
+
if (res) {
|
|
1052
|
+
const preferredWebexSite = MeetingsUtil.parseDefaultSiteFromMeetingPreferences(res);
|
|
1053
|
+
this.preferredWebexSite = preferredWebexSite;
|
|
1054
|
+
// @ts-ignore
|
|
1055
|
+
this.webex.internal.services._getCatalog().addAllowedDomains([preferredWebexSite]);
|
|
1056
|
+
}
|
|
1006
1057
|
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1058
|
+
// fall back to getting the preferred site from the user information
|
|
1059
|
+
if (!this.preferredWebexSite) {
|
|
1060
|
+
// @ts-ignore
|
|
1061
|
+
return this.webex.internal.user
|
|
1062
|
+
.get()
|
|
1063
|
+
.then((user) => {
|
|
1064
|
+
const preferredWebexSite =
|
|
1065
|
+
user?.userPreferences?.userPreferencesItems?.preferredWebExSite;
|
|
1066
|
+
if (preferredWebexSite) {
|
|
1067
|
+
this.preferredWebexSite = preferredWebexSite;
|
|
1068
|
+
// @ts-ignore
|
|
1069
|
+
this.webex.internal.services
|
|
1070
|
+
._getCatalog()
|
|
1071
|
+
.addAllowedDomains([preferredWebexSite]);
|
|
1072
|
+
} else {
|
|
1073
|
+
throw new Error('site not found');
|
|
1074
|
+
}
|
|
1075
|
+
})
|
|
1076
|
+
.catch(() => {
|
|
1077
|
+
LoggerProxy.logger.error(
|
|
1078
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1079
|
+
);
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
return Promise.resolve();
|
|
1084
|
+
});
|
|
1028
1085
|
}
|
|
1029
1086
|
|
|
1030
1087
|
return Promise.resolve();
|
|
@@ -1037,11 +1094,21 @@ export default class Meetings extends WebexPlugin {
|
|
|
1037
1094
|
* @public
|
|
1038
1095
|
* @memberof Meetings
|
|
1039
1096
|
*/
|
|
1040
|
-
|
|
1041
1097
|
getPersonalMeetingRoom() {
|
|
1042
1098
|
return this.personalMeetingRoom;
|
|
1043
1099
|
}
|
|
1044
1100
|
|
|
1101
|
+
/**
|
|
1102
|
+
* Returns basic information about a meeting that exists or
|
|
1103
|
+
* used to exist in the MeetingCollection
|
|
1104
|
+
*
|
|
1105
|
+
* @param {string} meetingId
|
|
1106
|
+
* @returns {BasicMeetingInformation|undefined}
|
|
1107
|
+
*/
|
|
1108
|
+
public getBasicMeetingInformation(meetingId: string): BasicMeetingInformation {
|
|
1109
|
+
return this.meetingCollection.get(meetingId) || this.deletedMeetings.get(meetingId);
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1045
1112
|
/**
|
|
1046
1113
|
* @param {Meeting} meeting
|
|
1047
1114
|
* @param {Object} reason
|
|
@@ -1052,6 +1119,24 @@ export default class Meetings extends WebexPlugin {
|
|
|
1052
1119
|
*/
|
|
1053
1120
|
private destroy(meeting: Meeting, reason: object) {
|
|
1054
1121
|
MeetingUtil.cleanUp(meeting);
|
|
1122
|
+
// keep some basic info about the deleted meeting forever
|
|
1123
|
+
this.deletedMeetings.set(meeting.id, {
|
|
1124
|
+
id: meeting.id,
|
|
1125
|
+
allowMediaInLobby: meeting.allowMediaInLobby,
|
|
1126
|
+
correlationId: meeting.correlationId,
|
|
1127
|
+
sessionCorrelationId: meeting.sessionCorrelationId,
|
|
1128
|
+
environment: meeting.environment,
|
|
1129
|
+
locusUrl: meeting.locusUrl,
|
|
1130
|
+
meetingInfo: cloneDeep(meeting.meetingInfo),
|
|
1131
|
+
locusInfo: {
|
|
1132
|
+
// locusInfo can be quite big, so keep just the minimal info
|
|
1133
|
+
url: meeting.locusInfo?.url,
|
|
1134
|
+
fullState: {
|
|
1135
|
+
lastActive: meeting.locusInfo?.fullState?.lastActive,
|
|
1136
|
+
sessionId: meeting.locusInfo?.fullState?.sessionId,
|
|
1137
|
+
},
|
|
1138
|
+
},
|
|
1139
|
+
});
|
|
1055
1140
|
this.meetingCollection.delete(meeting.id);
|
|
1056
1141
|
Trigger.trigger(
|
|
1057
1142
|
this,
|
|
@@ -1081,6 +1166,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1081
1166
|
* @param {CallStateForMetrics} callStateForMetrics - information about call state for metrics
|
|
1082
1167
|
* @param {Object} [meetingInfo] - Pre-fetched complete meeting info
|
|
1083
1168
|
* @param {String} [meetingLookupUrl] - meeting info prefetch url
|
|
1169
|
+
* @param {string} sessionCorrelationId - the optional specified sessionCorrelationId (callStateForMetrics.sessionCorrelationId) can be provided instead
|
|
1084
1170
|
* @returns {Promise<Meeting>} A new Meeting.
|
|
1085
1171
|
* @public
|
|
1086
1172
|
* @memberof Meetings
|
|
@@ -1094,7 +1180,8 @@ export default class Meetings extends WebexPlugin {
|
|
|
1094
1180
|
failOnMissingMeetingInfo = false,
|
|
1095
1181
|
callStateForMetrics: CallStateForMetrics = undefined,
|
|
1096
1182
|
meetingInfo = undefined,
|
|
1097
|
-
meetingLookupUrl = undefined
|
|
1183
|
+
meetingLookupUrl = undefined,
|
|
1184
|
+
sessionCorrelationId: string = undefined
|
|
1098
1185
|
) {
|
|
1099
1186
|
// Validate meeting information based on the provided destination and
|
|
1100
1187
|
// type. This must be performed prior to determining if the meeting is
|
|
@@ -1105,6 +1192,10 @@ export default class Meetings extends WebexPlugin {
|
|
|
1105
1192
|
callStateForMetrics = {...(callStateForMetrics || {}), correlationId};
|
|
1106
1193
|
}
|
|
1107
1194
|
|
|
1195
|
+
if (sessionCorrelationId) {
|
|
1196
|
+
callStateForMetrics = {...(callStateForMetrics || {}), sessionCorrelationId};
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1108
1199
|
return (
|
|
1109
1200
|
this.meetingInfo
|
|
1110
1201
|
.fetchInfoOptions(destination, type)
|
|
@@ -1176,10 +1267,9 @@ export default class Meetings extends WebexPlugin {
|
|
|
1176
1267
|
locusId: createdMeeting.locusId,
|
|
1177
1268
|
meetingId: createdMeeting.locusInfo?.info?.webExMeetingId,
|
|
1178
1269
|
autoupload: true,
|
|
1179
|
-
})
|
|
1180
|
-
} else {
|
|
1181
|
-
this.destroy(createdMeeting, payload.reason);
|
|
1270
|
+
});
|
|
1182
1271
|
}
|
|
1272
|
+
this.destroy(createdMeeting, payload.reason);
|
|
1183
1273
|
});
|
|
1184
1274
|
|
|
1185
1275
|
createdMeeting.on(EVENTS.REQUEST_UPLOAD_LOGS, (meetingInstance) => {
|
|
@@ -1206,7 +1296,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1206
1296
|
return Promise.resolve(createdMeeting);
|
|
1207
1297
|
});
|
|
1208
1298
|
}
|
|
1209
|
-
meeting.
|
|
1299
|
+
meeting.updateCallStateForMetrics(callStateForMetrics);
|
|
1210
1300
|
|
|
1211
1301
|
// Return the existing meeting.
|
|
1212
1302
|
return Promise.resolve(meeting);
|
|
@@ -1308,7 +1398,8 @@ export default class Meetings extends WebexPlugin {
|
|
|
1308
1398
|
if (
|
|
1309
1399
|
!(err instanceof CaptchaError) &&
|
|
1310
1400
|
!(err instanceof PasswordError) &&
|
|
1311
|
-
!(err instanceof PermissionError)
|
|
1401
|
+
!(err instanceof PermissionError) &&
|
|
1402
|
+
!(err instanceof WebinarRegistrationError)
|
|
1312
1403
|
) {
|
|
1313
1404
|
LoggerProxy.logger.info(
|
|
1314
1405
|
`Meetings:index#createMeeting --> Info Unable to fetch meeting info for ${destination}.`
|
package/src/metrics/constants.ts
CHANGED
|
@@ -70,6 +70,7 @@ const BEHAVIORAL_METRICS = {
|
|
|
70
70
|
ROAP_HTTP_RESPONSE_MISSING: 'js_sdk_roap_http_response_missing',
|
|
71
71
|
TURN_DISCOVERY_REQUIRES_OK: 'js_sdk_turn_discovery_requires_ok',
|
|
72
72
|
REACHABILITY_COMPLETED: 'js_sdk_reachability_completed',
|
|
73
|
+
WEBINAR_REGISTRATION_ERROR: 'js_sdk_webinar_registration_error',
|
|
73
74
|
};
|
|
74
75
|
|
|
75
76
|
export {BEHAVIORAL_METRICS as default};
|
|
@@ -107,11 +107,16 @@ export class RemoteMedia extends EventsScope {
|
|
|
107
107
|
* to restrict the requested resolution to this size
|
|
108
108
|
* @param width width of the video element
|
|
109
109
|
* @param height height of the video element
|
|
110
|
+
* @note width/height of 0 will be ignored
|
|
110
111
|
*/
|
|
111
112
|
public setSizeHint(width, height) {
|
|
112
113
|
// only base on height for now
|
|
113
114
|
let fs: number;
|
|
114
115
|
|
|
116
|
+
if (width === 0 || height === 0) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
115
120
|
if (height < 135) {
|
|
116
121
|
fs = 60;
|
|
117
122
|
} else if (height < 270) {
|
package/src/roap/request.ts
CHANGED
|
@@ -79,7 +79,9 @@ export default class RoapRequest extends StatelessWebexPlugin {
|
|
|
79
79
|
});
|
|
80
80
|
|
|
81
81
|
LoggerProxy.logger.info(
|
|
82
|
-
`Roap:request#sendRoap --> ${
|
|
82
|
+
`Roap:request#sendRoap --> ${roapMessage.messageType} seq:${roapMessage.seq} ${
|
|
83
|
+
ipVersion ? `ipver=${ipVersion} ` : ''
|
|
84
|
+
} ${locusSelfUrl}`
|
|
83
85
|
);
|
|
84
86
|
|
|
85
87
|
return locusMediaRequest
|
|
@@ -1807,6 +1807,35 @@ describe('plugin-meetings', () => {
|
|
|
1807
1807
|
assert.calledWith(locusInfo.applyLocusDeltaData, action, parsedLoci, fakeMeeting);
|
|
1808
1808
|
});
|
|
1809
1809
|
|
|
1810
|
+
it('catches errors thrown by onDeltaAction and is able to process next Locus delta', () => {
|
|
1811
|
+
const fakeLocusDelta = {
|
|
1812
|
+
sequence: {
|
|
1813
|
+
rangeStart: 0,
|
|
1814
|
+
rangeEnd: 0,
|
|
1815
|
+
},
|
|
1816
|
+
};
|
|
1817
|
+
locusInfo.locusParser.workingCopy = {
|
|
1818
|
+
sequence: {
|
|
1819
|
+
rangeStart: 0,
|
|
1820
|
+
rangeEnd: 0,
|
|
1821
|
+
},
|
|
1822
|
+
};
|
|
1823
|
+
const testMeeting = {locusInfo: {onDeltaLocus: sinon.stub()}};
|
|
1824
|
+
|
|
1825
|
+
locusParser.onDeltaAction = sandbox
|
|
1826
|
+
.stub()
|
|
1827
|
+
.onCall(0)
|
|
1828
|
+
.callsFake(() => {
|
|
1829
|
+
throw new Error('fake error');
|
|
1830
|
+
});
|
|
1831
|
+
|
|
1832
|
+
// simulate first locus delta coming - it will trigger an error thrown by onDeltaAction
|
|
1833
|
+
locusInfo.handleLocusDelta(fakeLocusDelta, testMeeting);
|
|
1834
|
+
|
|
1835
|
+
// simulate a second locus delta coming - it should be processed without errors
|
|
1836
|
+
locusInfo.handleLocusDelta(fakeLocusDelta, testMeeting);
|
|
1837
|
+
});
|
|
1838
|
+
|
|
1810
1839
|
it('applyLocusDeltaData handles USE_INCOMING action correctly', () => {
|
|
1811
1840
|
const {USE_INCOMING} = LocusDeltaParser.loci;
|
|
1812
1841
|
const meeting = {
|
|
@@ -83,6 +83,7 @@ describe('createMediaConnection', () => {
|
|
|
83
83
|
username: 'turn username',
|
|
84
84
|
password: 'turn password',
|
|
85
85
|
},
|
|
86
|
+
iceCandidatesTimeout: undefined,
|
|
86
87
|
});
|
|
87
88
|
assert.calledOnce(roapMediaConnectionConstructorStub);
|
|
88
89
|
assert.calledWith(
|
|
@@ -100,6 +101,7 @@ describe('createMediaConnection', () => {
|
|
|
100
101
|
credential: 'turn password',
|
|
101
102
|
},
|
|
102
103
|
],
|
|
104
|
+
iceCandidatesTimeout: undefined,
|
|
103
105
|
skipInactiveTransceivers: false,
|
|
104
106
|
requireH264: true,
|
|
105
107
|
sdpMunging: {
|
|
@@ -306,12 +308,14 @@ describe('createMediaConnection', () => {
|
|
|
306
308
|
enableRtx: ENABLE_RTX,
|
|
307
309
|
enableExtmap: ENABLE_EXTMAP,
|
|
308
310
|
turnServerInfo,
|
|
311
|
+
iceCandidatesTimeout: undefined,
|
|
309
312
|
});
|
|
310
313
|
assert.calledOnce(roapMediaConnectionConstructorStub);
|
|
311
314
|
assert.calledWith(
|
|
312
315
|
roapMediaConnectionConstructorStub,
|
|
313
316
|
{
|
|
314
317
|
iceServers: [],
|
|
318
|
+
iceCandidatesTimeout: undefined,
|
|
315
319
|
skipInactiveTransceivers: false,
|
|
316
320
|
requireH264: true,
|
|
317
321
|
sdpMunging: {
|
|
@@ -78,6 +78,7 @@ describe('plugin-meetings', () => {
|
|
|
78
78
|
supportHDV: null,
|
|
79
79
|
canShareWhiteBoard: null,
|
|
80
80
|
enforceVirtualBackground: null,
|
|
81
|
+
canPollingAndQA: null,
|
|
81
82
|
...expected,
|
|
82
83
|
};
|
|
83
84
|
|
|
@@ -161,6 +162,7 @@ describe('plugin-meetings', () => {
|
|
|
161
162
|
'supportHDV',
|
|
162
163
|
'canShareWhiteBoard',
|
|
163
164
|
'enforceVirtualBackground',
|
|
165
|
+
'canPollingAndQA',
|
|
164
166
|
].forEach((key) => {
|
|
165
167
|
it(`get and set for ${key} work as expected`, () => {
|
|
166
168
|
const inMeetingActions = new InMeetingActions();
|