@webex/plugin-meetings 1.150.1 → 1.151.3
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/constants.js +3 -1
- package/dist/constants.js.map +1 -1
- package/dist/meeting/index.js +170 -4
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting-info/utilv2.js +81 -37
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/metrics/index.js +65 -45
- package/dist/metrics/index.js.map +1 -1
- package/dist/peer-connection-manager/index.js +1 -1
- package/dist/peer-connection-manager/index.js.map +1 -1
- package/package.json +6 -5
- package/src/constants.js +2 -0
- package/src/meeting/index.js +171 -10
- package/src/meeting-info/utilv2.js +30 -5
- package/src/metrics/index.js +28 -17
- package/src/peer-connection-manager/index.js +7 -2
- package/test/integration/spec/journey.js +10 -7
- package/test/integration/spec/space-meeting.js +8 -3
- package/test/unit/spec/meeting/index.js +0 -1
- package/test/unit/spec/meeting-info/utilv2.js +65 -4
- package/test/unit/spec/metrics/index.js +42 -1
- package/test/utils/testUtils.js +18 -1
package/src/meeting/index.js
CHANGED
|
@@ -51,6 +51,7 @@ import {
|
|
|
51
51
|
MEETING_STATE_MACHINE,
|
|
52
52
|
MEETING_STATE,
|
|
53
53
|
MEETINGS,
|
|
54
|
+
METRICS_JOIN_TIMES_MAX_DURATION,
|
|
54
55
|
METRICS_OPERATIONAL_MEASURES,
|
|
55
56
|
MQA_STATS,
|
|
56
57
|
NETWORK_STATUS,
|
|
@@ -1065,10 +1066,45 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1065
1066
|
};
|
|
1066
1067
|
}
|
|
1067
1068
|
|
|
1069
|
+
const localSDPGenRemoteSDPRecv = this.getLocalSDPGenRemoteSDPRecvDelay();
|
|
1070
|
+
|
|
1071
|
+
if (localSDPGenRemoteSDPRecv) {
|
|
1072
|
+
options.joinTimes = {
|
|
1073
|
+
...options.joinTimes,
|
|
1074
|
+
localSDPGenRemoteSDPRecv
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
const callInitiateJoinReq = this.getCallInitiateJoinReq();
|
|
1079
|
+
|
|
1080
|
+
if (callInitiateJoinReq) {
|
|
1081
|
+
options.joinTimes = {
|
|
1082
|
+
...options.joinTimes,
|
|
1083
|
+
callInitiateJoinReq
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
const joinReqResp = this.getJoinReqResp();
|
|
1088
|
+
|
|
1089
|
+
if (joinReqResp) {
|
|
1090
|
+
options.joinTimes = {
|
|
1091
|
+
...options.joinTimes,
|
|
1092
|
+
joinReqResp
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
const getTotalJmt = this.getTotalJmt();
|
|
1097
|
+
|
|
1098
|
+
if (getTotalJmt) {
|
|
1099
|
+
options.joinTimes = {
|
|
1100
|
+
...options.joinTimes,
|
|
1101
|
+
getTotalJmt
|
|
1102
|
+
};
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1068
1105
|
if (options.type === MQA_STATS.CA_TYPE) {
|
|
1069
1106
|
payload = Metrics.initMediaPayload(options.event, identifiers, options);
|
|
1070
1107
|
}
|
|
1071
|
-
|
|
1072
1108
|
else {
|
|
1073
1109
|
payload = Metrics.initPayload(options.event, identifiers, options);
|
|
1074
1110
|
}
|
|
@@ -3372,12 +3408,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3372
3408
|
}
|
|
3373
3409
|
}
|
|
3374
3410
|
|
|
3375
|
-
return MeetingUtil.joinMeetingOptions(this, options)
|
|
3376
|
-
|
|
3377
|
-
|
|
3411
|
+
return MeetingUtil.joinMeetingOptions(this, options)
|
|
3412
|
+
.then((join) => {
|
|
3413
|
+
this.meetingFiniteStateMachine.join();
|
|
3414
|
+
LoggerProxy.logger.log('Meeting:index#join --> Success');
|
|
3378
3415
|
|
|
3379
|
-
|
|
3380
|
-
|
|
3416
|
+
return join;
|
|
3417
|
+
})
|
|
3381
3418
|
.then((join) => {
|
|
3382
3419
|
joinSuccess(join);
|
|
3383
3420
|
this.deferJoin = undefined;
|
|
@@ -3851,7 +3888,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3851
3888
|
meetingId: this.id,
|
|
3852
3889
|
remoteQualityLevel: this.mediaProperties.remoteQualityLevel,
|
|
3853
3890
|
enableRtx: this.config.enableRtx,
|
|
3854
|
-
enableExtmap: this.config.enableExtmap
|
|
3891
|
+
enableExtmap: this.config.enableExtmap,
|
|
3892
|
+
setStartLocalSDPGenRemoteSDPRecvDelay: this.setStartLocalSDPGenRemoteSDPRecvDelay.bind(this)
|
|
3855
3893
|
})
|
|
3856
3894
|
.then((peerConnection) => this.getDevices().then((devices) => {
|
|
3857
3895
|
MeetingUtil.handleDeviceLogging(devices);
|
|
@@ -5238,9 +5276,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5238
5276
|
}
|
|
5239
5277
|
|
|
5240
5278
|
/**
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5279
|
+
* @param {string} typeMedia 'audio' or 'video'
|
|
5280
|
+
* @returns {undefined}
|
|
5281
|
+
*/
|
|
5244
5282
|
setEndSendingMediaDelay(typeMedia) {
|
|
5245
5283
|
this[`endSendingMediaDelay${typeMedia}`] = performance.now();
|
|
5246
5284
|
}
|
|
@@ -5255,4 +5293,127 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5255
5293
|
|
|
5256
5294
|
return (start && end) ? end - start : undefined;
|
|
5257
5295
|
}
|
|
5296
|
+
|
|
5297
|
+
/**
|
|
5298
|
+
*
|
|
5299
|
+
* @returns {undefined}
|
|
5300
|
+
*/
|
|
5301
|
+
setStartLocalSDPGenRemoteSDPRecvDelay() {
|
|
5302
|
+
if (!this.startLocalSDPGenRemoteSDPRecvDelay) {
|
|
5303
|
+
this.startLocalSDPGenRemoteSDPRecvDelay = performance.now();
|
|
5304
|
+
this.endLocalSDPGenRemoteSDPRecvDelay = undefined;
|
|
5305
|
+
}
|
|
5306
|
+
}
|
|
5307
|
+
|
|
5308
|
+
/**
|
|
5309
|
+
*
|
|
5310
|
+
* @returns {undefined}
|
|
5311
|
+
*/
|
|
5312
|
+
setEndLocalSDPGenRemoteSDPRecvDelay() {
|
|
5313
|
+
if (!this.endLocalSDPGenRemoteSDPRecvDelay) {
|
|
5314
|
+
this.endLocalSDPGenRemoteSDPRecvDelay = performance.now();
|
|
5315
|
+
}
|
|
5316
|
+
}
|
|
5317
|
+
|
|
5318
|
+
/**
|
|
5319
|
+
*
|
|
5320
|
+
* @returns {string} duration between local SDP generation and remote SDP reception
|
|
5321
|
+
*/
|
|
5322
|
+
getLocalSDPGenRemoteSDPRecvDelay() {
|
|
5323
|
+
const start = this.startLocalSDPGenRemoteSDPRecvDelay;
|
|
5324
|
+
const end = this.endLocalSDPGenRemoteSDPRecvDelay;
|
|
5325
|
+
|
|
5326
|
+
if (start && end) {
|
|
5327
|
+
const calculatedDelay = end - start;
|
|
5328
|
+
|
|
5329
|
+
return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ?
|
|
5330
|
+
undefined :
|
|
5331
|
+
calculatedDelay;
|
|
5332
|
+
}
|
|
5333
|
+
|
|
5334
|
+
return undefined;
|
|
5335
|
+
}
|
|
5336
|
+
|
|
5337
|
+
/**
|
|
5338
|
+
*
|
|
5339
|
+
* @returns {undefined}
|
|
5340
|
+
*/
|
|
5341
|
+
setStartCallInitiateJoinReq() {
|
|
5342
|
+
this.startCallInitiateJoinReq = performance.now();
|
|
5343
|
+
this.endCallInitiateJoinReq = undefined;
|
|
5344
|
+
}
|
|
5345
|
+
|
|
5346
|
+
/**
|
|
5347
|
+
*
|
|
5348
|
+
* @returns {undefined}
|
|
5349
|
+
*/
|
|
5350
|
+
setEndCallInitiateJoinReq() {
|
|
5351
|
+
this.endCallInitiateJoinReq = performance.now();
|
|
5352
|
+
}
|
|
5353
|
+
|
|
5354
|
+
/**
|
|
5355
|
+
*
|
|
5356
|
+
* @returns {string} duration between call initiate and sending join request to locus
|
|
5357
|
+
*/
|
|
5358
|
+
getCallInitiateJoinReq() {
|
|
5359
|
+
const start = this.startCallInitiateJoinReq;
|
|
5360
|
+
const end = this.endCallInitiateJoinReq;
|
|
5361
|
+
|
|
5362
|
+
if (start && end) {
|
|
5363
|
+
const calculatedDelay = end - start;
|
|
5364
|
+
|
|
5365
|
+
return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ?
|
|
5366
|
+
undefined :
|
|
5367
|
+
calculatedDelay;
|
|
5368
|
+
}
|
|
5369
|
+
|
|
5370
|
+
return undefined;
|
|
5371
|
+
}
|
|
5372
|
+
|
|
5373
|
+
/**
|
|
5374
|
+
*
|
|
5375
|
+
* @returns {undefined}
|
|
5376
|
+
*/
|
|
5377
|
+
setStartJoinReqResp() {
|
|
5378
|
+
this.startJoinReqResp = performance.now();
|
|
5379
|
+
this.endJoinReqResp = undefined;
|
|
5380
|
+
}
|
|
5381
|
+
|
|
5382
|
+
/**
|
|
5383
|
+
*
|
|
5384
|
+
* @returns {undefined}
|
|
5385
|
+
*/
|
|
5386
|
+
setEndJoinReqResp() {
|
|
5387
|
+
this.endJoinReqResp = performance.now();
|
|
5388
|
+
}
|
|
5389
|
+
|
|
5390
|
+
/**
|
|
5391
|
+
*
|
|
5392
|
+
* @returns {string} duration between sending locus join request and receiving join response
|
|
5393
|
+
*/
|
|
5394
|
+
getJoinReqResp() {
|
|
5395
|
+
const start = this.startJoinReqResp;
|
|
5396
|
+
const end = this.endJoinReqResp;
|
|
5397
|
+
|
|
5398
|
+
if (start && end) {
|
|
5399
|
+
const calculatedDelay = end - start;
|
|
5400
|
+
|
|
5401
|
+
return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ?
|
|
5402
|
+
undefined :
|
|
5403
|
+
calculatedDelay;
|
|
5404
|
+
}
|
|
5405
|
+
|
|
5406
|
+
return undefined;
|
|
5407
|
+
}
|
|
5408
|
+
|
|
5409
|
+
/**
|
|
5410
|
+
*
|
|
5411
|
+
* @returns {string} duration between call initiate and successful locus join (even if it is in lobby)
|
|
5412
|
+
*/
|
|
5413
|
+
getTotalJmt() {
|
|
5414
|
+
const start = this.startCallInitiateJoinReq;
|
|
5415
|
+
const end = this.endJoinReqResp;
|
|
5416
|
+
|
|
5417
|
+
return (start && end) ? end - start : undefined;
|
|
5418
|
+
}
|
|
5258
5419
|
}
|
|
@@ -21,7 +21,8 @@ import {
|
|
|
21
21
|
MEET,
|
|
22
22
|
MEET_M,
|
|
23
23
|
HTTPS_PROTOCOL,
|
|
24
|
-
UUID_REG
|
|
24
|
+
UUID_REG,
|
|
25
|
+
VALID_EMAIL_ADDRESS
|
|
25
26
|
} from '../constants';
|
|
26
27
|
import ParameterError from '../common/errors/parameter';
|
|
27
28
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
@@ -116,8 +117,27 @@ MeetingInfoUtil.getSipUriFromHydraPersonId = (destination, webex) => webex.peopl
|
|
|
116
117
|
|
|
117
118
|
|
|
118
119
|
MeetingInfoUtil.getDestinationType = async (from) => {
|
|
119
|
-
const {
|
|
120
|
+
const {type, webex} = from;
|
|
121
|
+
let {destination} = from;
|
|
122
|
+
|
|
123
|
+
if (type === _PERSONAL_ROOM_) { // this case checks if your type is personal room
|
|
124
|
+
if (!destination) { // if we are not getting anything in desination we fetch org and user ids from webex instance
|
|
125
|
+
destination = {
|
|
126
|
+
userId: webex.internal.device.userId,
|
|
127
|
+
orgId: webex.internal.device.orgId
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
const options = VALID_EMAIL_ADDRESS.test(destination) ? {email: destination} : {id: destination};// we are assuming userId as default
|
|
132
|
+
const res = await webex.people.list(options);
|
|
133
|
+
|
|
134
|
+
let {orgId, id: userId} = res.items[0];
|
|
120
135
|
|
|
136
|
+
userId = deconstructHydraId(userId).id;
|
|
137
|
+
orgId = deconstructHydraId(orgId).id;
|
|
138
|
+
destination = {userId, orgId};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
121
141
|
if (type) {
|
|
122
142
|
return {
|
|
123
143
|
destination,
|
|
@@ -193,15 +213,17 @@ MeetingInfoUtil.getDestinationType = async (from) => {
|
|
|
193
213
|
*/
|
|
194
214
|
MeetingInfoUtil.getRequestBody = (options) => {
|
|
195
215
|
const {type, destination} = options;
|
|
196
|
-
const body = {
|
|
216
|
+
const body = {
|
|
217
|
+
supportHostKey: true
|
|
218
|
+
};
|
|
197
219
|
|
|
198
220
|
switch (type) {
|
|
199
221
|
case _SIP_URI_:
|
|
200
222
|
body.sipUrl = destination;
|
|
201
223
|
break;
|
|
202
224
|
case _PERSONAL_ROOM_:
|
|
203
|
-
body.userId = destination;
|
|
204
|
-
body.orgId =
|
|
225
|
+
body.userId = destination.userId;
|
|
226
|
+
body.orgId = destination.orgId;
|
|
205
227
|
break;
|
|
206
228
|
case _MEETING_ID_:
|
|
207
229
|
body.meetingKey = destination;
|
|
@@ -214,6 +236,9 @@ MeetingInfoUtil.getRequestBody = (options) => {
|
|
|
214
236
|
if (destination.info?.webExMeetingId) {
|
|
215
237
|
body.meetingKey = destination.info.webExMeetingId;
|
|
216
238
|
}
|
|
239
|
+
else if (destination.info?.sipUri) {
|
|
240
|
+
body.sipUrl = destination.info.sipUri;
|
|
241
|
+
}
|
|
217
242
|
break;
|
|
218
243
|
case _MEETING_LINK_:
|
|
219
244
|
body.meetingUrl = destination;
|
package/src/metrics/index.js
CHANGED
|
@@ -6,10 +6,10 @@ import util from 'util';
|
|
|
6
6
|
import {includes} from 'lodash';
|
|
7
7
|
import uuid from 'uuid';
|
|
8
8
|
import window from 'global/window';
|
|
9
|
+
import anonymize from 'ip-anonymize';
|
|
9
10
|
|
|
10
11
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
11
12
|
import {MEETING_ERRORS} from '../constants';
|
|
12
|
-
import StaticConfig from '../common/config';
|
|
13
13
|
import BrowserDetection from '../common/browser-detection';
|
|
14
14
|
|
|
15
15
|
import {
|
|
@@ -34,21 +34,19 @@ const {
|
|
|
34
34
|
} = BrowserDetection();
|
|
35
35
|
|
|
36
36
|
// Apply a CIDR /28 format to the IP address
|
|
37
|
-
const
|
|
38
|
-
if (!localIp) {
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
const parts = localIp.split('.');
|
|
42
|
-
|
|
43
|
-
// eslint-disable-next-line no-bitwise
|
|
44
|
-
parts[3] &= 240;
|
|
45
|
-
|
|
46
|
-
return parts.join('.');
|
|
47
|
-
};
|
|
37
|
+
const anonymizeIPAddress = (localIp) => anonymize(localIp);
|
|
48
38
|
|
|
49
39
|
const triggerTimers = ({event, meeting, data}) => {
|
|
50
40
|
switch (event) {
|
|
41
|
+
case eventType.CALL_INITIATED:
|
|
42
|
+
meeting.setStartCallInitiateJoinReq();
|
|
43
|
+
break;
|
|
44
|
+
case eventType.LOCUS_JOIN_REQUEST:
|
|
45
|
+
meeting.setEndCallInitiateJoinReq();
|
|
46
|
+
meeting.setStartJoinReqResp();
|
|
47
|
+
break;
|
|
51
48
|
case eventType.LOCUS_JOIN_RESPONSE:
|
|
49
|
+
meeting.setEndJoinReqResp();
|
|
52
50
|
meeting.setStartSetupDelay(mediaType.AUDIO);
|
|
53
51
|
meeting.setStartSetupDelay(mediaType.VIDEO);
|
|
54
52
|
meeting.setStartSendingMediaDelay(mediaType.AUDIO);
|
|
@@ -60,6 +58,12 @@ const triggerTimers = ({event, meeting, data}) => {
|
|
|
60
58
|
case eventType.SENDING_MEDIA_START:
|
|
61
59
|
meeting.setEndSendingMediaDelay(data.mediaType);
|
|
62
60
|
break;
|
|
61
|
+
case eventType.LOCAL_SDP_GENERATED:
|
|
62
|
+
meeting.setStartLocalSDPGenRemoteSDPRecvDelay();
|
|
63
|
+
break;
|
|
64
|
+
case eventType.REMOTE_SDP_RECEIVED:
|
|
65
|
+
meeting.setEndLocalSDPGenRemoteSDPRecvDelay();
|
|
66
|
+
break;
|
|
63
67
|
default:
|
|
64
68
|
break;
|
|
65
69
|
}
|
|
@@ -144,6 +148,7 @@ class Metrics {
|
|
|
144
148
|
|
|
145
149
|
if (!meeting && meetingId) {
|
|
146
150
|
meeting = this.meetingCollection.get(meetingId);
|
|
151
|
+
options.meeting = meeting;
|
|
147
152
|
}
|
|
148
153
|
|
|
149
154
|
if (meeting) {
|
|
@@ -185,7 +190,7 @@ class Metrics {
|
|
|
185
190
|
clientInfo: {
|
|
186
191
|
clientType: options.clientType,
|
|
187
192
|
clientVersion: `${CLIENT_NAME}/${this.webex.version}`,
|
|
188
|
-
localNetworkPrefix:
|
|
193
|
+
localNetworkPrefix: anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress),
|
|
189
194
|
osVersion: getOSVersion() || 'unknown',
|
|
190
195
|
subClientType: options.subClientType,
|
|
191
196
|
os: this.getOsName(),
|
|
@@ -228,6 +233,9 @@ class Metrics {
|
|
|
228
233
|
if (options.recoveredBy) {
|
|
229
234
|
payload.event.recoveredBy = options.recoveredBy;
|
|
230
235
|
}
|
|
236
|
+
if (options.joinTimes) {
|
|
237
|
+
payload.event.joinTimes = options.joinTimes;
|
|
238
|
+
}
|
|
231
239
|
}
|
|
232
240
|
|
|
233
241
|
return payload;
|
|
@@ -259,7 +267,7 @@ class Metrics {
|
|
|
259
267
|
* @memberof Metrics
|
|
260
268
|
*/
|
|
261
269
|
initMediaPayload(eventType, identifiers, options = {}) {
|
|
262
|
-
const {audioSetupDelay, videoSetupDelay} = options;
|
|
270
|
+
const {audioSetupDelay, videoSetupDelay, joinTimes} = options;
|
|
263
271
|
|
|
264
272
|
const payload = {
|
|
265
273
|
eventId: uuid.v4(),
|
|
@@ -273,7 +281,7 @@ class Metrics {
|
|
|
273
281
|
clientInfo: {
|
|
274
282
|
clientType: options.clientType, // TODO: Only clientType: 'TEAMS_CLIENT' is whitelisted
|
|
275
283
|
clientVersion: `${CLIENT_NAME}/${this.webex.version}`,
|
|
276
|
-
localNetworkPrefix:
|
|
284
|
+
localNetworkPrefix: anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress),
|
|
277
285
|
os: this.getOsName(),
|
|
278
286
|
osVersion: getOSVersion() || UNKNOWN,
|
|
279
287
|
subClientType: options.subClientType,
|
|
@@ -290,7 +298,10 @@ class Metrics {
|
|
|
290
298
|
canProceed: true,
|
|
291
299
|
identifiers,
|
|
292
300
|
intervals: [options.intervalData],
|
|
293
|
-
|
|
301
|
+
joinTimes,
|
|
302
|
+
eventData: {
|
|
303
|
+
webClientDomain: window.location.hostname
|
|
304
|
+
},
|
|
294
305
|
sourceMetadata: {
|
|
295
306
|
applicationSoftwareType: CLIENT_NAME,
|
|
296
307
|
applicationSoftwareVersion: this.webex.version,
|
|
@@ -455,7 +466,7 @@ class Metrics {
|
|
|
455
466
|
userAgentToString() {
|
|
456
467
|
let userAgentOption;
|
|
457
468
|
let browserInfo;
|
|
458
|
-
const clientInfo = util.format('client=%s', `${
|
|
469
|
+
const clientInfo = util.format('client=%s', `${this.webex.meetings?.metrics?.clientName}`);
|
|
459
470
|
|
|
460
471
|
if (['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !== -1) {
|
|
461
472
|
browserInfo = util.format('browser=%s', `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`);
|
|
@@ -288,7 +288,12 @@ pc.addStream = (peerConnection, stream) => {
|
|
|
288
288
|
* @param {String} meetingId
|
|
289
289
|
* @returns {undefined}
|
|
290
290
|
*/
|
|
291
|
-
pc.setRemoteSessionDetails = (
|
|
291
|
+
pc.setRemoteSessionDetails = (
|
|
292
|
+
peerConnection,
|
|
293
|
+
typeStr,
|
|
294
|
+
remoteSdp,
|
|
295
|
+
meetingId,
|
|
296
|
+
) => {
|
|
292
297
|
LoggerProxy.logger.log(`PeerConnectionManager:index#setRemoteSessionDetails --> Setting the remote description type: ${typeStr}State: ${peerConnection.signalingState}`);
|
|
293
298
|
const sdp = remoteSdp;
|
|
294
299
|
|
|
@@ -314,7 +319,7 @@ pc.setRemoteSessionDetails = (peerConnection, typeStr, remoteSdp, meetingId) =>
|
|
|
314
319
|
})
|
|
315
320
|
)
|
|
316
321
|
.then(() => {
|
|
317
|
-
if (
|
|
322
|
+
if (peerConnection.signalingState === SDP.STABLE) {
|
|
318
323
|
Metrics.postEvent({
|
|
319
324
|
event: eventType.REMOTE_SDP_RECEIVED,
|
|
320
325
|
meetingId
|
|
@@ -519,7 +519,10 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
519
519
|
.then((response) => {
|
|
520
520
|
assert.equal(response[0].result.memberId, alice.meeting.selfId);
|
|
521
521
|
}),
|
|
522
|
-
testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
|
|
522
|
+
testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
|
|
523
|
+
.then((response) => {
|
|
524
|
+
console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
525
|
+
}),
|
|
523
526
|
testUtils.waitForEvents([{scope: alice.meeting, event: 'media:ready'}])
|
|
524
527
|
.then((response) => {
|
|
525
528
|
console.log('MEDIA:READY event ', response[0].result);
|
|
@@ -549,7 +552,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
549
552
|
}),
|
|
550
553
|
testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
|
|
551
554
|
.then((response) => {
|
|
552
|
-
console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response));
|
|
555
|
+
console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
553
556
|
}),
|
|
554
557
|
testUtils.waitForEvents([{scope: bob.meeting, event: 'media:ready'}])
|
|
555
558
|
.then((response) => {
|
|
@@ -601,7 +604,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
601
604
|
}),
|
|
602
605
|
testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
|
|
603
606
|
.then((response) => {
|
|
604
|
-
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response));
|
|
607
|
+
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
605
608
|
})
|
|
606
609
|
])
|
|
607
610
|
.then(() => {
|
|
@@ -624,7 +627,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
624
627
|
}),
|
|
625
628
|
testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
|
|
626
629
|
.then((response) => {
|
|
627
|
-
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response));
|
|
630
|
+
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
628
631
|
})
|
|
629
632
|
])
|
|
630
633
|
.then(() => {
|
|
@@ -660,7 +663,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
660
663
|
}),
|
|
661
664
|
testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
|
|
662
665
|
.then((response) => {
|
|
663
|
-
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response));
|
|
666
|
+
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
664
667
|
})
|
|
665
668
|
])
|
|
666
669
|
.then(() => {
|
|
@@ -679,7 +682,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
679
682
|
}),
|
|
680
683
|
testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
|
|
681
684
|
.then((response) => {
|
|
682
|
-
console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response));
|
|
685
|
+
console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
683
686
|
}),
|
|
684
687
|
testUtils.waitForEvents([{scope: bob.meeting, event: 'media:ready'}])
|
|
685
688
|
.then((response) => {
|
|
@@ -715,7 +718,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
715
718
|
}),
|
|
716
719
|
testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
|
|
717
720
|
.then((response) => {
|
|
718
|
-
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response));
|
|
721
|
+
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
719
722
|
})
|
|
720
723
|
])
|
|
721
724
|
.then(() => {
|
|
@@ -65,8 +65,14 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
65
65
|
testUtils.delayedPromise(alice.meeting.join()),
|
|
66
66
|
testUtils.waitForEvents([
|
|
67
67
|
{scope: bob.webex.meetings, event: 'meeting:added', user: bob},
|
|
68
|
-
{scope: chris.webex.meetings, event: 'meeting:added', user: chris}
|
|
69
|
-
|
|
68
|
+
{scope: chris.webex.meetings, event: 'meeting:added', user: chris}
|
|
69
|
+
])
|
|
70
|
+
]).then(() => {
|
|
71
|
+
// TODO Renenable after unified flag is enabled
|
|
72
|
+
// const {meetingNumber} = bob.meeting.meetingInfo;
|
|
73
|
+
|
|
74
|
+
// assert(meetingNumber === alice.meeting.meetingNumber, 'meetingNumber matches alice meeting number');
|
|
75
|
+
})));
|
|
70
76
|
|
|
71
77
|
xit('Should fetch user info using user hydra id with the new api', () => alice.webex.rooms.create({title: 'sample'})
|
|
72
78
|
.then((room) => MeetingInfoUtil.getDestinationType({
|
|
@@ -95,7 +101,6 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
95
101
|
assert(meetingNumber === alice.meeting.meetingNumber, 'meetingNumber matches alice meeting number');
|
|
96
102
|
});
|
|
97
103
|
|
|
98
|
-
|
|
99
104
|
it('Bob and chris joins space meeting', () => testUtils.waitForStateChange(alice.meeting, 'JOINED')
|
|
100
105
|
.then(() => testUtils.waitForStateChange(bob.meeting, 'IDLE'))
|
|
101
106
|
.then(() => testUtils.waitForStateChange(chris.meeting, 'IDLE'))
|
|
@@ -110,7 +110,6 @@ describe('plugin-meetings', () => {
|
|
|
110
110
|
|
|
111
111
|
|
|
112
112
|
TriggerProxy.trigger = sinon.stub().returns(true);
|
|
113
|
-
Metrics.initPayload = sinon.stub();
|
|
114
113
|
Metrics.postEvent = sinon.stub();
|
|
115
114
|
Metrics.initialSetup(null, webex);
|
|
116
115
|
MediaUtil.createPeerConnection = sinon.stub().returns({});
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {assert} from '@webex/test-helper-chai';
|
|
5
|
+
import {assert, expect} from '@webex/test-helper-chai';
|
|
6
6
|
import sinon from 'sinon';
|
|
7
7
|
import {
|
|
8
8
|
_MEETING_ID_,
|
|
@@ -68,17 +68,78 @@ describe('plugin-meetings', () => {
|
|
|
68
68
|
assert.equal(res.type, _CONVERSATION_URL_);
|
|
69
69
|
assert.equal(res.destination, 'https://conv-a.wbx2.com/conversation/api/v1/conversations/bfb49280');
|
|
70
70
|
});
|
|
71
|
+
|
|
72
|
+
describe('PMR', () => {
|
|
73
|
+
const mockedListReturn = {userId: '01824b9b-adef-4b10-b5c1-8a2fe2fb7c0e', orgId: '1eb65fdf-9643-417f-9974-ad72cae0e10f'};
|
|
74
|
+
const mockedList = {
|
|
75
|
+
items: [{
|
|
76
|
+
id: 'Y2lzY29zcGFyazovL3VzL1BFT1BMRS8wMTgyNGI5Yi1hZGVmLTRiMTAtYjVjMS04YTJmZTJmYjdjMGU',
|
|
77
|
+
orgId: 'Y2lzY29zcGFyazovL3VzL09SR0FOSVpBVElPTi8xZWI2NWZkZi05NjQzLTQxN2YtOTk3NC1hZDcyY2FlMGUxMGY'
|
|
78
|
+
}]
|
|
79
|
+
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
it('should return a userID and orgID without passing a destination', async () => {
|
|
83
|
+
const res = await MeetingInfoUtil.getDestinationType({
|
|
84
|
+
type: _PERSONAL_ROOM_,
|
|
85
|
+
webex: {
|
|
86
|
+
internal: {
|
|
87
|
+
device: {
|
|
88
|
+
userId: '01824b9b-adef-4b10-b5c1-8a2fe2fb7c0e',
|
|
89
|
+
orgId: '1eb65fdf-9643-417f-9974-ad72cae0e10f'
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
expect(res.destination.userId).to.equal('01824b9b-adef-4b10-b5c1-8a2fe2fb7c0e');
|
|
96
|
+
expect(res.destination.orgId).to.equal('1eb65fdf-9643-417f-9974-ad72cae0e10f');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should return a userID and orgID when passing an email', async () => {
|
|
100
|
+
const res = await MeetingInfoUtil.getDestinationType({
|
|
101
|
+
type: _PERSONAL_ROOM_,
|
|
102
|
+
destination: 'amritesi@cisco.com',
|
|
103
|
+
webex: {
|
|
104
|
+
people: {list: sinon.stub().returns(mockedList)}
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
const {orgId, userId} = res.destination;
|
|
109
|
+
|
|
110
|
+
expect(userId).to.equal(mockedListReturn.userId);
|
|
111
|
+
expect(orgId).to.equal(mockedListReturn.orgId);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should return a userID and orgID when passing an id', async () => {
|
|
115
|
+
const res = await MeetingInfoUtil.getDestinationType({
|
|
116
|
+
type: _PERSONAL_ROOM_,
|
|
117
|
+
destination: '01824b9b-adef-4b10-b5c1-8a2fe2fb7c0e',
|
|
118
|
+
webex: {
|
|
119
|
+
people: {list: sinon.stub().returns(mockedList)}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
});
|
|
123
|
+
const {orgId, userId} = res.destination;
|
|
124
|
+
|
|
125
|
+
expect(userId).to.equal(mockedListReturn.userId);
|
|
126
|
+
expect(orgId).to.equal(mockedListReturn.orgId);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
71
129
|
});
|
|
72
130
|
|
|
73
131
|
describe('#getRequestBody', () => {
|
|
74
132
|
it('for _PERSONAL_ROOM_', () => {
|
|
75
133
|
const res = MeetingInfoUtil.getRequestBody({
|
|
76
134
|
type: _PERSONAL_ROOM_,
|
|
77
|
-
destination:
|
|
135
|
+
destination: {
|
|
136
|
+
userId: '01824b9b-adef-4b10-b5c1-8a2fe2fb7c0e',
|
|
137
|
+
orgId: '1eb65fdf-9643-417f-9974-ad72cae0e10f'
|
|
138
|
+
}
|
|
78
139
|
});
|
|
79
140
|
|
|
80
|
-
assert.equal(res.orgId, '');
|
|
81
|
-
assert.equal(res.userId, '
|
|
141
|
+
assert.equal(res.orgId, '1eb65fdf-9643-417f-9974-ad72cae0e10f');
|
|
142
|
+
assert.equal(res.userId, '01824b9b-adef-4b10-b5c1-8a2fe2fb7c0e');
|
|
82
143
|
});
|
|
83
144
|
|
|
84
145
|
it('for _MEETING_ID_', () => {
|
|
@@ -24,6 +24,14 @@ const {
|
|
|
24
24
|
browserOnly(describe)('Meeting metrics', () => {
|
|
25
25
|
let webex, mockSubmitMetric, sandbox;
|
|
26
26
|
|
|
27
|
+
const geoHintInfo = {
|
|
28
|
+
clientAddress: '2001:0db8:0000:08d3:0000:0000:0070:0000',
|
|
29
|
+
clientRegion: 'US-WEST',
|
|
30
|
+
countryCode: 'US',
|
|
31
|
+
regionCode: 'US-WEST',
|
|
32
|
+
timezone: 'America/Los_Angeles'
|
|
33
|
+
};
|
|
34
|
+
|
|
27
35
|
beforeEach(() => {
|
|
28
36
|
sandbox = sinon.createSandbox();
|
|
29
37
|
mockSubmitMetric = sandbox.stub();
|
|
@@ -40,7 +48,6 @@ browserOnly(describe)('Meeting metrics', () => {
|
|
|
40
48
|
clientId: 'mock-client-id'
|
|
41
49
|
}
|
|
42
50
|
};
|
|
43
|
-
|
|
44
51
|
webex.internal.metrics.submitClientMetrics = mockSubmitMetric;
|
|
45
52
|
metrics.initialSetup({}, webex);
|
|
46
53
|
});
|
|
@@ -49,6 +56,40 @@ browserOnly(describe)('Meeting metrics', () => {
|
|
|
49
56
|
sandbox.restore();
|
|
50
57
|
});
|
|
51
58
|
|
|
59
|
+
describe('initPayload / initMediaPayload', () => {
|
|
60
|
+
it('should create payload with masked IPv4', () => {
|
|
61
|
+
geoHintInfo.clientAddress = '128.0.0.1';
|
|
62
|
+
webex.meetings = {
|
|
63
|
+
geoHintInfo
|
|
64
|
+
};
|
|
65
|
+
metrics.initialSetup({}, webex);
|
|
66
|
+
const payload = metrics.initPayload('myMetric', {}, {clientType: 'TEAMS_CLIENT'});
|
|
67
|
+
|
|
68
|
+
assert(payload.origin.clientInfo.localNetworkPrefix === '128.0.0.0');
|
|
69
|
+
assert(payload.event.name === 'myMetric');
|
|
70
|
+
|
|
71
|
+
const payload2 = metrics.initMediaPayload('myMetric', {}, {clientType: 'TEAMS_CLIENT'});
|
|
72
|
+
|
|
73
|
+
assert(payload2.origin.clientInfo.localNetworkPrefix === '128.0.0.0');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should create payload with masked IPv6', () => {
|
|
77
|
+
geoHintInfo.clientAddress = '2001:0db8:0000:08d3:0000:0000:0070:0000';
|
|
78
|
+
webex.meetings = {
|
|
79
|
+
geoHintInfo
|
|
80
|
+
};
|
|
81
|
+
metrics.initialSetup({}, webex);
|
|
82
|
+
const payload = metrics.initPayload('myIPv6Metric', {}, {clientType: 'TEAMS_CLIENT'});
|
|
83
|
+
|
|
84
|
+
assert(payload.origin.clientInfo.localNetworkPrefix === '2001:d00::');
|
|
85
|
+
assert(payload.event.name === 'myIPv6Metric');
|
|
86
|
+
|
|
87
|
+
const payload2 = metrics.initMediaPayload('myIPv6Metric', {}, {clientType: 'TEAMS_CLIENT'});
|
|
88
|
+
|
|
89
|
+
assert(payload2.origin.clientInfo.localNetworkPrefix === '2001:d00::');
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
52
93
|
describe('#sendOperationalMetric', () => {
|
|
53
94
|
it('sends client metric via Metrics plugin', () => {
|
|
54
95
|
metrics.sendOperationalMetric('myMetric');
|