@webex/plugin-meetings 3.5.0 → 3.6.0-next.2
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/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +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 +133 -87
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/util.js +8 -10
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +100 -26
- package/dist/meetings/index.js.map +1 -1
- package/dist/roap/request.js +1 -1
- package/dist/roap/request.js.map +1 -1
- package/dist/types/config.d.ts +2 -0
- package/dist/types/constants.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/meetings/index.d.ts +43 -2
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/config.ts +3 -0
- package/src/constants.ts +1 -0
- package/src/media/index.ts +4 -1
- package/src/meeting/in-meeting-actions.ts +3 -0
- package/src/meeting/index.ts +57 -2
- package/src/meeting/util.ts +27 -31
- package/src/meetings/index.ts +126 -37
- package/src/roap/request.ts +3 -1
- 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 +58 -17
- package/test/unit/spec/meeting/utils.js +50 -85
- package/test/unit/spec/meetings/index.js +128 -13
- 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
|
|
|
@@ -133,6 +134,28 @@ class MediaLogger {
|
|
|
133
134
|
* @memberof Meetings
|
|
134
135
|
*/
|
|
135
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Object containing only the most basic information about a meeting.
|
|
139
|
+
* This is the information that is kept even after the meeting is deleted from the MeetingCollection
|
|
140
|
+
*/
|
|
141
|
+
export type BasicMeetingInformation = {
|
|
142
|
+
allowMediaInLobby: boolean;
|
|
143
|
+
correlationId: string;
|
|
144
|
+
environment: string;
|
|
145
|
+
id: string;
|
|
146
|
+
locusUrl: string;
|
|
147
|
+
locusInfo: {
|
|
148
|
+
// it's only a very small subset of the locus info, to avoid using much memory
|
|
149
|
+
url: string;
|
|
150
|
+
fullState: {
|
|
151
|
+
lastActive: string;
|
|
152
|
+
sessionId: string;
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
meetingInfo: any;
|
|
156
|
+
sessionCorrelationId: string;
|
|
157
|
+
};
|
|
158
|
+
|
|
136
159
|
/**
|
|
137
160
|
* Maintain a cache of meetings and sync with services.
|
|
138
161
|
* @class
|
|
@@ -141,6 +164,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
141
164
|
loggerRequest: any;
|
|
142
165
|
media: any;
|
|
143
166
|
meetingCollection: any;
|
|
167
|
+
deletedMeetings: Map<string, BasicMeetingInformation>;
|
|
144
168
|
personalMeetingRoom: any;
|
|
145
169
|
preferredWebexSite: any;
|
|
146
170
|
reachability: Reachability;
|
|
@@ -191,6 +215,8 @@ export default class Meetings extends WebexPlugin {
|
|
|
191
215
|
// @ts-ignore
|
|
192
216
|
this.loggerRequest = new LoggerRequest({webex: this.webex});
|
|
193
217
|
this.meetingCollection = new MeetingCollection();
|
|
218
|
+
this.deletedMeetings = new Map();
|
|
219
|
+
|
|
194
220
|
/**
|
|
195
221
|
* The PersonalMeetingRoom object to interact with server
|
|
196
222
|
* @instance
|
|
@@ -736,15 +762,35 @@ export default class Meetings extends WebexPlugin {
|
|
|
736
762
|
}
|
|
737
763
|
}
|
|
738
764
|
|
|
765
|
+
/**
|
|
766
|
+
* API to toggle backend ipv6 native support config, needs to be called before webex.meetings.register()
|
|
767
|
+
*
|
|
768
|
+
* @param {Boolean} newValue
|
|
769
|
+
* @private
|
|
770
|
+
* @memberof Meetings
|
|
771
|
+
* @returns {undefined}
|
|
772
|
+
*/
|
|
773
|
+
private _toggleIpv6BackendNativeSupport(newValue: boolean) {
|
|
774
|
+
if (typeof newValue !== 'boolean') {
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
// @ts-ignore
|
|
778
|
+
if (this.config.backendIpv6NativeSupport !== newValue) {
|
|
779
|
+
// @ts-ignore
|
|
780
|
+
this.config.backendIpv6NativeSupport = newValue;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
|
|
739
784
|
/**
|
|
740
785
|
* Explicitly sets up the meetings plugin by registering
|
|
741
786
|
* the device, connecting to mercury, and listening for locus events.
|
|
742
787
|
*
|
|
788
|
+
* @param {DeviceRegistrationOptions} [deviceRegistrationOptions] - The options for registering the device (optional)
|
|
743
789
|
* @returns {Promise}
|
|
744
790
|
* @public
|
|
745
791
|
* @memberof Meetings
|
|
746
792
|
*/
|
|
747
|
-
public register() {
|
|
793
|
+
public register(deviceRegistrationOptions?: DeviceRegistrationOptions): Promise<any> {
|
|
748
794
|
// @ts-ignore
|
|
749
795
|
if (!this.webex.canAuthorize) {
|
|
750
796
|
LoggerProxy.logger.error(
|
|
@@ -770,7 +816,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
770
816
|
}),
|
|
771
817
|
// @ts-ignore
|
|
772
818
|
this.webex.internal.device
|
|
773
|
-
.register()
|
|
819
|
+
.register(deviceRegistrationOptions)
|
|
774
820
|
// @ts-ignore
|
|
775
821
|
.then(() =>
|
|
776
822
|
LoggerProxy.logger.info(
|
|
@@ -996,35 +1042,45 @@ export default class Meetings extends WebexPlugin {
|
|
|
996
1042
|
* @memberof Meetings
|
|
997
1043
|
*/
|
|
998
1044
|
fetchUserPreferredWebexSite() {
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1045
|
+
// @ts-ignore
|
|
1046
|
+
return this.webex.people._getMe().then((me) => {
|
|
1047
|
+
const isGuestUser = me.type === 'appuser';
|
|
1048
|
+
if (!isGuestUser) {
|
|
1049
|
+
return this.request.getMeetingPreferences().then((res) => {
|
|
1050
|
+
if (res) {
|
|
1051
|
+
const preferredWebexSite = MeetingsUtil.parseDefaultSiteFromMeetingPreferences(res);
|
|
1052
|
+
this.preferredWebexSite = preferredWebexSite;
|
|
1053
|
+
// @ts-ignore
|
|
1054
|
+
this.webex.internal.services._getCatalog().addAllowedDomains([preferredWebexSite]);
|
|
1055
|
+
}
|
|
1006
1056
|
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1057
|
+
// fall back to getting the preferred site from the user information
|
|
1058
|
+
if (!this.preferredWebexSite) {
|
|
1059
|
+
// @ts-ignore
|
|
1060
|
+
return this.webex.internal.user
|
|
1061
|
+
.get()
|
|
1062
|
+
.then((user) => {
|
|
1063
|
+
const preferredWebexSite =
|
|
1064
|
+
user?.userPreferences?.userPreferencesItems?.preferredWebExSite;
|
|
1065
|
+
if (preferredWebexSite) {
|
|
1066
|
+
this.preferredWebexSite = preferredWebexSite;
|
|
1067
|
+
// @ts-ignore
|
|
1068
|
+
this.webex.internal.services
|
|
1069
|
+
._getCatalog()
|
|
1070
|
+
.addAllowedDomains([preferredWebexSite]);
|
|
1071
|
+
} else {
|
|
1072
|
+
throw new Error('site not found');
|
|
1073
|
+
}
|
|
1074
|
+
})
|
|
1075
|
+
.catch(() => {
|
|
1076
|
+
LoggerProxy.logger.error(
|
|
1077
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1078
|
+
);
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
return Promise.resolve();
|
|
1083
|
+
});
|
|
1028
1084
|
}
|
|
1029
1085
|
|
|
1030
1086
|
return Promise.resolve();
|
|
@@ -1037,11 +1093,21 @@ export default class Meetings extends WebexPlugin {
|
|
|
1037
1093
|
* @public
|
|
1038
1094
|
* @memberof Meetings
|
|
1039
1095
|
*/
|
|
1040
|
-
|
|
1041
1096
|
getPersonalMeetingRoom() {
|
|
1042
1097
|
return this.personalMeetingRoom;
|
|
1043
1098
|
}
|
|
1044
1099
|
|
|
1100
|
+
/**
|
|
1101
|
+
* Returns basic information about a meeting that exists or
|
|
1102
|
+
* used to exist in the MeetingCollection
|
|
1103
|
+
*
|
|
1104
|
+
* @param {string} meetingId
|
|
1105
|
+
* @returns {BasicMeetingInformation|undefined}
|
|
1106
|
+
*/
|
|
1107
|
+
public getBasicMeetingInformation(meetingId: string): BasicMeetingInformation {
|
|
1108
|
+
return this.meetingCollection.get(meetingId) || this.deletedMeetings.get(meetingId);
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1045
1111
|
/**
|
|
1046
1112
|
* @param {Meeting} meeting
|
|
1047
1113
|
* @param {Object} reason
|
|
@@ -1052,6 +1118,24 @@ export default class Meetings extends WebexPlugin {
|
|
|
1052
1118
|
*/
|
|
1053
1119
|
private destroy(meeting: Meeting, reason: object) {
|
|
1054
1120
|
MeetingUtil.cleanUp(meeting);
|
|
1121
|
+
// keep some basic info about the deleted meeting forever
|
|
1122
|
+
this.deletedMeetings.set(meeting.id, {
|
|
1123
|
+
id: meeting.id,
|
|
1124
|
+
allowMediaInLobby: meeting.allowMediaInLobby,
|
|
1125
|
+
correlationId: meeting.correlationId,
|
|
1126
|
+
sessionCorrelationId: meeting.sessionCorrelationId,
|
|
1127
|
+
environment: meeting.environment,
|
|
1128
|
+
locusUrl: meeting.locusUrl,
|
|
1129
|
+
meetingInfo: cloneDeep(meeting.meetingInfo),
|
|
1130
|
+
locusInfo: {
|
|
1131
|
+
// locusInfo can be quite big, so keep just the minimal info
|
|
1132
|
+
url: meeting.locusInfo?.url,
|
|
1133
|
+
fullState: {
|
|
1134
|
+
lastActive: meeting.locusInfo?.fullState?.lastActive,
|
|
1135
|
+
sessionId: meeting.locusInfo?.fullState?.sessionId,
|
|
1136
|
+
},
|
|
1137
|
+
},
|
|
1138
|
+
});
|
|
1055
1139
|
this.meetingCollection.delete(meeting.id);
|
|
1056
1140
|
Trigger.trigger(
|
|
1057
1141
|
this,
|
|
@@ -1081,6 +1165,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1081
1165
|
* @param {CallStateForMetrics} callStateForMetrics - information about call state for metrics
|
|
1082
1166
|
* @param {Object} [meetingInfo] - Pre-fetched complete meeting info
|
|
1083
1167
|
* @param {String} [meetingLookupUrl] - meeting info prefetch url
|
|
1168
|
+
* @param {string} sessionCorrelationId - the optional specified sessionCorrelationId (callStateForMetrics.sessionCorrelationId) can be provided instead
|
|
1084
1169
|
* @returns {Promise<Meeting>} A new Meeting.
|
|
1085
1170
|
* @public
|
|
1086
1171
|
* @memberof Meetings
|
|
@@ -1094,7 +1179,8 @@ export default class Meetings extends WebexPlugin {
|
|
|
1094
1179
|
failOnMissingMeetingInfo = false,
|
|
1095
1180
|
callStateForMetrics: CallStateForMetrics = undefined,
|
|
1096
1181
|
meetingInfo = undefined,
|
|
1097
|
-
meetingLookupUrl = undefined
|
|
1182
|
+
meetingLookupUrl = undefined,
|
|
1183
|
+
sessionCorrelationId: string = undefined
|
|
1098
1184
|
) {
|
|
1099
1185
|
// Validate meeting information based on the provided destination and
|
|
1100
1186
|
// type. This must be performed prior to determining if the meeting is
|
|
@@ -1105,6 +1191,10 @@ export default class Meetings extends WebexPlugin {
|
|
|
1105
1191
|
callStateForMetrics = {...(callStateForMetrics || {}), correlationId};
|
|
1106
1192
|
}
|
|
1107
1193
|
|
|
1194
|
+
if (sessionCorrelationId) {
|
|
1195
|
+
callStateForMetrics = {...(callStateForMetrics || {}), sessionCorrelationId};
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1108
1198
|
return (
|
|
1109
1199
|
this.meetingInfo
|
|
1110
1200
|
.fetchInfoOptions(destination, type)
|
|
@@ -1176,10 +1266,9 @@ export default class Meetings extends WebexPlugin {
|
|
|
1176
1266
|
locusId: createdMeeting.locusId,
|
|
1177
1267
|
meetingId: createdMeeting.locusInfo?.info?.webExMeetingId,
|
|
1178
1268
|
autoupload: true,
|
|
1179
|
-
})
|
|
1180
|
-
} else {
|
|
1181
|
-
this.destroy(createdMeeting, payload.reason);
|
|
1269
|
+
});
|
|
1182
1270
|
}
|
|
1271
|
+
this.destroy(createdMeeting, payload.reason);
|
|
1183
1272
|
});
|
|
1184
1273
|
|
|
1185
1274
|
createdMeeting.on(EVENTS.REQUEST_UPLOAD_LOGS, (meetingInstance) => {
|
|
@@ -1206,7 +1295,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1206
1295
|
return Promise.resolve(createdMeeting);
|
|
1207
1296
|
});
|
|
1208
1297
|
}
|
|
1209
|
-
meeting.
|
|
1298
|
+
meeting.updateCallStateForMetrics(callStateForMetrics);
|
|
1210
1299
|
|
|
1211
1300
|
// Return the existing meeting.
|
|
1212
1301
|
return Promise.resolve(meeting);
|
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
|
|
@@ -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();
|
|
@@ -5,7 +5,6 @@ import 'jsdom-global/register';
|
|
|
5
5
|
import {cloneDeep, forEach, isEqual, isUndefined} from 'lodash';
|
|
6
6
|
import sinon from 'sinon';
|
|
7
7
|
import * as InternalMediaCoreModule from '@webex/internal-media-core';
|
|
8
|
-
import * as RtcMetricsModule from '@webex/plugin-meetings/src/rtcMetrics';
|
|
9
8
|
import * as RemoteMediaManagerModule from '@webex/plugin-meetings/src/multistream/remoteMediaManager';
|
|
10
9
|
import StateMachine from 'javascript-state-machine';
|
|
11
10
|
import uuid from 'uuid';
|
|
@@ -307,7 +306,7 @@ describe('plugin-meetings', () => {
|
|
|
307
306
|
assert.equal(meeting.resource, uuid2);
|
|
308
307
|
assert.equal(meeting.deviceUrl, uuid3);
|
|
309
308
|
assert.equal(meeting.correlationId, correlationId);
|
|
310
|
-
assert.deepEqual(meeting.callStateForMetrics, {correlationId});
|
|
309
|
+
assert.deepEqual(meeting.callStateForMetrics, {correlationId, sessionCorrelationId: ''});
|
|
311
310
|
assert.deepEqual(meeting.meetingInfo, {});
|
|
312
311
|
assert.instanceOf(meeting.members, Members);
|
|
313
312
|
assert.calledOnceWithExactly(
|
|
@@ -376,7 +375,7 @@ describe('plugin-meetings', () => {
|
|
|
376
375
|
}
|
|
377
376
|
);
|
|
378
377
|
assert.equal(newMeeting.correlationId, newMeeting.id);
|
|
379
|
-
assert.deepEqual(newMeeting.callStateForMetrics, {correlationId: newMeeting.id});
|
|
378
|
+
assert.deepEqual(newMeeting.callStateForMetrics, {correlationId: newMeeting.id, sessionCorrelationId: ''});
|
|
380
379
|
});
|
|
381
380
|
|
|
382
381
|
it('correlationId can be provided in callStateForMetrics', () => {
|
|
@@ -403,6 +402,37 @@ describe('plugin-meetings', () => {
|
|
|
403
402
|
correlationId: uuid4,
|
|
404
403
|
joinTrigger: 'fake-join-trigger',
|
|
405
404
|
loginType: 'fake-login-type',
|
|
405
|
+
sessionCorrelationId: '',
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
it('sessionCorrelationId can be provided in callStateForMetrics', () => {
|
|
410
|
+
const newMeeting = new Meeting(
|
|
411
|
+
{
|
|
412
|
+
userId: uuid1,
|
|
413
|
+
resource: uuid2,
|
|
414
|
+
deviceUrl: uuid3,
|
|
415
|
+
locus: {url: url1},
|
|
416
|
+
destination: testDestination,
|
|
417
|
+
destinationType: DESTINATION_TYPE.MEETING_ID,
|
|
418
|
+
callStateForMetrics: {
|
|
419
|
+
correlationId: uuid4,
|
|
420
|
+
sessionCorrelationId: uuid1,
|
|
421
|
+
joinTrigger: 'fake-join-trigger',
|
|
422
|
+
loginType: 'fake-login-type',
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
parent: webex,
|
|
427
|
+
}
|
|
428
|
+
);
|
|
429
|
+
assert.exists(newMeeting.sessionCorrelationId);
|
|
430
|
+
assert.equal(newMeeting.sessionCorrelationId, uuid1);
|
|
431
|
+
assert.deepEqual(newMeeting.callStateForMetrics, {
|
|
432
|
+
correlationId: uuid4,
|
|
433
|
+
sessionCorrelationId: uuid1,
|
|
434
|
+
joinTrigger: 'fake-join-trigger',
|
|
435
|
+
loginType: 'fake-login-type',
|
|
406
436
|
});
|
|
407
437
|
});
|
|
408
438
|
|
|
@@ -1611,7 +1641,6 @@ describe('plugin-meetings', () => {
|
|
|
1611
1641
|
|
|
1612
1642
|
assert.calledOnce(MeetingUtil.joinMeeting);
|
|
1613
1643
|
assert.calledOnce(webex.internal.device.meetingStarted);
|
|
1614
|
-
assert.calledOnce(meeting.setLocus);
|
|
1615
1644
|
assert.equal(result, joinMeetingResult);
|
|
1616
1645
|
assert.calledWith(webex.internal.llm.on, 'online', meeting.handleLLMOnline);
|
|
1617
1646
|
});
|
|
@@ -2456,8 +2485,8 @@ describe('plugin-meetings', () => {
|
|
|
2456
2485
|
});
|
|
2457
2486
|
|
|
2458
2487
|
it('should create rtcMetrics and pass them to Media.createMediaConnection()', async () => {
|
|
2459
|
-
const
|
|
2460
|
-
|
|
2488
|
+
const setIntervalOriginal = window.setInterval;
|
|
2489
|
+
window.setInterval = sinon.stub().returns(1);
|
|
2461
2490
|
|
|
2462
2491
|
// setup the minimum mocks required for multistream connection
|
|
2463
2492
|
fakeMediaConnection.createSendSlot = sinon.stub().returns({
|
|
@@ -2478,8 +2507,6 @@ describe('plugin-meetings', () => {
|
|
|
2478
2507
|
mediaSettings: {},
|
|
2479
2508
|
});
|
|
2480
2509
|
|
|
2481
|
-
assert.calledOnceWithExactly(rtcMetricsCtor, webex, meeting.id, meeting.correlationId);
|
|
2482
|
-
|
|
2483
2510
|
// check that rtcMetrics was passed to Media.createMediaConnection
|
|
2484
2511
|
assert.calledOnce(Media.createMediaConnection);
|
|
2485
2512
|
assert.calledWith(
|
|
@@ -2487,10 +2514,10 @@ describe('plugin-meetings', () => {
|
|
|
2487
2514
|
true,
|
|
2488
2515
|
meeting.getMediaConnectionDebugId(),
|
|
2489
2516
|
meeting.id,
|
|
2490
|
-
sinon.match(
|
|
2491
|
-
rtcMetrics: fakeRtcMetrics,
|
|
2492
|
-
})
|
|
2517
|
+
sinon.match.hasNested('rtcMetrics.webex', webex)
|
|
2493
2518
|
);
|
|
2519
|
+
|
|
2520
|
+
window.setInterval = setIntervalOriginal;
|
|
2494
2521
|
});
|
|
2495
2522
|
|
|
2496
2523
|
it('should pass the turn server info to the peer connection', async () => {
|
|
@@ -3677,6 +3704,7 @@ describe('plugin-meetings', () => {
|
|
|
3677
3704
|
credential: 'turn password',
|
|
3678
3705
|
},
|
|
3679
3706
|
],
|
|
3707
|
+
iceCandidatesTimeout: meeting.config.iceCandidatesGatheringTimeout,
|
|
3680
3708
|
skipInactiveTransceivers: false,
|
|
3681
3709
|
requireH264: true,
|
|
3682
3710
|
sdpMunging: {
|
|
@@ -3761,11 +3789,16 @@ describe('plugin-meetings', () => {
|
|
|
3761
3789
|
// that's being tested in these tests)
|
|
3762
3790
|
meeting.webex.meetings.registered = true;
|
|
3763
3791
|
meeting.webex.internal.device.config = {};
|
|
3764
|
-
sinon.stub(MeetingUtil, '
|
|
3792
|
+
sinon.stub(MeetingUtil, 'parseLocusJoin').returns({
|
|
3765
3793
|
id: 'fake locus from mocked join request',
|
|
3766
3794
|
locusUrl: 'fake locus url',
|
|
3767
3795
|
mediaId: 'fake media id',
|
|
3768
|
-
})
|
|
3796
|
+
})
|
|
3797
|
+
sinon.stub(meeting.meetingRequest, 'joinMeeting').resolves({
|
|
3798
|
+
headers: {
|
|
3799
|
+
trackingid: 'fake tracking id',
|
|
3800
|
+
}
|
|
3801
|
+
})
|
|
3769
3802
|
await meeting.join({enableMultistream: isMultistream});
|
|
3770
3803
|
});
|
|
3771
3804
|
|
|
@@ -6927,33 +6960,36 @@ describe('plugin-meetings', () => {
|
|
|
6927
6960
|
describe('#setCorrelationId', () => {
|
|
6928
6961
|
it('should set the correlationId and return undefined', () => {
|
|
6929
6962
|
assert.equal(meeting.correlationId, correlationId);
|
|
6930
|
-
assert.deepEqual(meeting.callStateForMetrics, {correlationId});
|
|
6963
|
+
assert.deepEqual(meeting.callStateForMetrics, {correlationId, sessionCorrelationId: ''});
|
|
6931
6964
|
meeting.setCorrelationId(uuid1);
|
|
6932
6965
|
assert.equal(meeting.correlationId, uuid1);
|
|
6933
|
-
assert.deepEqual(meeting.callStateForMetrics, {correlationId: uuid1});
|
|
6966
|
+
assert.deepEqual(meeting.callStateForMetrics, {correlationId: uuid1, sessionCorrelationId: ''});
|
|
6934
6967
|
});
|
|
6935
6968
|
});
|
|
6936
6969
|
|
|
6937
6970
|
describe('#updateCallStateForMetrics', () => {
|
|
6938
6971
|
it('should update the callState, overriding existing values', () => {
|
|
6939
|
-
assert.deepEqual(meeting.callStateForMetrics, {correlationId});
|
|
6972
|
+
assert.deepEqual(meeting.callStateForMetrics, {correlationId, sessionCorrelationId: ''});
|
|
6940
6973
|
meeting.updateCallStateForMetrics({
|
|
6941
6974
|
correlationId: uuid1,
|
|
6975
|
+
sessionCorrelationId: uuid3,
|
|
6942
6976
|
joinTrigger: 'jt',
|
|
6943
6977
|
loginType: 'lt',
|
|
6944
6978
|
});
|
|
6945
6979
|
assert.deepEqual(meeting.callStateForMetrics, {
|
|
6946
6980
|
correlationId: uuid1,
|
|
6981
|
+
sessionCorrelationId: uuid3,
|
|
6947
6982
|
joinTrigger: 'jt',
|
|
6948
6983
|
loginType: 'lt',
|
|
6949
6984
|
});
|
|
6950
6985
|
});
|
|
6951
6986
|
|
|
6952
6987
|
it('should update the callState, keeping non-supplied values', () => {
|
|
6953
|
-
assert.deepEqual(meeting.callStateForMetrics, {correlationId});
|
|
6988
|
+
assert.deepEqual(meeting.callStateForMetrics, {correlationId, sessionCorrelationId: ''});
|
|
6954
6989
|
meeting.updateCallStateForMetrics({joinTrigger: 'jt', loginType: 'lt'});
|
|
6955
6990
|
assert.deepEqual(meeting.callStateForMetrics, {
|
|
6956
6991
|
correlationId,
|
|
6992
|
+
sessionCorrelationId: '',
|
|
6957
6993
|
joinTrigger: 'jt',
|
|
6958
6994
|
loginType: 'lt',
|
|
6959
6995
|
});
|
|
@@ -9837,6 +9873,11 @@ describe('plugin-meetings', () => {
|
|
|
9837
9873
|
requiredDisplayHints: [],
|
|
9838
9874
|
requiredPolicies: [SELF_POLICY.SUPPORT_ANNOTATION],
|
|
9839
9875
|
},
|
|
9876
|
+
{
|
|
9877
|
+
actionName: 'canPollingAndQA',
|
|
9878
|
+
requiredDisplayHints: [],
|
|
9879
|
+
requiredPolicies: [SELF_POLICY.SUPPORT_POLLING_AND_QA],
|
|
9880
|
+
},
|
|
9840
9881
|
],
|
|
9841
9882
|
({
|
|
9842
9883
|
actionName,
|