@webex/internal-plugin-metrics 3.0.0 → 3.1.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/call-diagnostic/call-diagnostic-metrics-latencies.js +90 -14
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.js +60 -38
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js +10 -3
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
- package/dist/client-metrics-prelogin-batcher.js +32 -0
- package/dist/client-metrics-prelogin-batcher.js.map +1 -0
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +10 -25
- package/dist/metrics.js.map +1 -1
- package/dist/metrics.types.js.map +1 -1
- package/dist/new-metrics.js +5 -4
- package/dist/new-metrics.js.map +1 -1
- package/dist/prelogin-metrics-batcher.js +1 -1
- package/dist/prelogin-metrics-batcher.js.map +1 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +41 -8
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +17 -12
- package/dist/types/client-metrics-prelogin-batcher.d.ts +2 -0
- package/dist/types/index.d.ts +2 -3
- package/dist/types/metrics.types.d.ts +3 -1
- package/package.json +12 -13
- package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +89 -13
- package/src/call-diagnostic/call-diagnostic-metrics.ts +35 -8
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +17 -3
- package/src/client-metrics-prelogin-batcher.ts +26 -0
- package/src/index.ts +2 -2
- package/src/metrics.js +8 -23
- package/src/metrics.types.ts +12 -1
- package/src/new-metrics.ts +2 -2
- package/src/prelogin-metrics-batcher.ts +1 -1
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +25 -15
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +199 -1
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +155 -41
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +28 -7
- package/test/unit/spec/client-metrics-prelogin-batcher.ts +54 -0
- package/test/unit/spec/metrics.js +9 -31
- package/test/unit/spec/new-metrics.ts +29 -31
- package/test/unit/spec/prelogin-metrics-batcher.ts +13 -10
|
@@ -114,6 +114,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
114
114
|
sinon.useFakeTimers(now.getTime());
|
|
115
115
|
cd = new CallDiagnosticMetrics({}, {parent: webex});
|
|
116
116
|
sinon.stub(uuid, 'v4').returns('my-fake-id');
|
|
117
|
+
cd.setDeviceInfo(webex.internal.device);
|
|
117
118
|
});
|
|
118
119
|
|
|
119
120
|
afterEach(() => {
|
|
@@ -223,6 +224,43 @@ describe('internal-plugin-metrics', () => {
|
|
|
223
224
|
});
|
|
224
225
|
});
|
|
225
226
|
|
|
227
|
+
it('should build origin correctly with browserLaunchMethod', () => {
|
|
228
|
+
sinon.stub(CallDiagnosticUtils, 'anonymizeIPAddress').returns('1.1.1.1');
|
|
229
|
+
|
|
230
|
+
//@ts-ignore
|
|
231
|
+
const res = cd.getOrigin(
|
|
232
|
+
{
|
|
233
|
+
subClientType: 'WEB_APP',
|
|
234
|
+
clientType: 'TEAMS_CLIENT',
|
|
235
|
+
newEnvironment: 'test-new-env',
|
|
236
|
+
clientLaunchMethod: 'url-handler',
|
|
237
|
+
browserLaunchMethod: 'thinclient',
|
|
238
|
+
},
|
|
239
|
+
fakeMeeting.id
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
assert.deepEqual(res, {
|
|
243
|
+
clientInfo: {
|
|
244
|
+
browser: getBrowserName(),
|
|
245
|
+
browserVersion: getBrowserVersion(),
|
|
246
|
+
clientType: 'TEAMS_CLIENT',
|
|
247
|
+
clientVersion: 'webex-js-sdk/webex-version',
|
|
248
|
+
publicNetworkPrefix: '1.1.1.1',
|
|
249
|
+
localNetworkPrefix: '1.1.1.1',
|
|
250
|
+
os: getOSNameInternal(),
|
|
251
|
+
osVersion: getOSVersion(),
|
|
252
|
+
subClientType: 'WEB_APP',
|
|
253
|
+
clientLaunchMethod: 'url-handler',
|
|
254
|
+
browserLaunchMethod: 'thinclient',
|
|
255
|
+
},
|
|
256
|
+
environment: 'meeting_evn',
|
|
257
|
+
newEnvironment: 'test-new-env',
|
|
258
|
+
name: 'endpoint',
|
|
259
|
+
networkType: 'unknown',
|
|
260
|
+
userAgent,
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
226
264
|
it('should build origin correctly with no meeting', () => {
|
|
227
265
|
sinon.stub(CallDiagnosticUtils, 'anonymizeIPAddress').returns('1.1.1.1');
|
|
228
266
|
|
|
@@ -302,6 +340,11 @@ describe('internal-plugin-metrics', () => {
|
|
|
302
340
|
|
|
303
341
|
describe('#getIdentifiers', () => {
|
|
304
342
|
it('should build identifiers correctly', () => {
|
|
343
|
+
cd.device = {
|
|
344
|
+
...cd.device,
|
|
345
|
+
config: {installationId: 'installationId'},
|
|
346
|
+
};
|
|
347
|
+
|
|
305
348
|
const res = cd.getIdentifiers({
|
|
306
349
|
mediaConnections: [
|
|
307
350
|
{mediaAgentAlias: 'mediaAgentAlias', mediaAgentGroupId: 'mediaAgentGroupId'},
|
|
@@ -315,6 +358,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
315
358
|
locusId: 'url',
|
|
316
359
|
locusStartTime: 'lastActive',
|
|
317
360
|
locusUrl: 'locus/url',
|
|
361
|
+
machineId: 'installationId',
|
|
318
362
|
mediaAgentAlias: 'mediaAgentAlias',
|
|
319
363
|
mediaAgentGroupId: 'mediaAgentGroupId',
|
|
320
364
|
orgId: 'orgId',
|
|
@@ -478,7 +522,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
478
522
|
});
|
|
479
523
|
|
|
480
524
|
it('should build identifiers correctly given preLoginId and no device userId available', () => {
|
|
481
|
-
|
|
525
|
+
cd.device.userId = undefined;
|
|
482
526
|
|
|
483
527
|
const res = cd.getIdentifiers({
|
|
484
528
|
correlationId: 'correlationId',
|
|
@@ -498,7 +542,10 @@ describe('internal-plugin-metrics', () => {
|
|
|
498
542
|
it('should prepare diagnostic event successfully', () => {
|
|
499
543
|
const options = {meetingId: fakeMeeting.id};
|
|
500
544
|
const getOriginStub = sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
|
|
501
|
-
const clearEmptyKeysRecursivelyStub = sinon.stub(
|
|
545
|
+
const clearEmptyKeysRecursivelyStub = sinon.stub(
|
|
546
|
+
CallDiagnosticUtils,
|
|
547
|
+
'clearEmptyKeysRecursively'
|
|
548
|
+
);
|
|
502
549
|
|
|
503
550
|
const res = cd.prepareDiagnosticEvent(
|
|
504
551
|
{
|
|
@@ -663,7 +710,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
663
710
|
});
|
|
664
711
|
|
|
665
712
|
const webexLoggerLogCalls = webex.logger.log.getCalls();
|
|
666
|
-
assert.deepEqual(webexLoggerLogCalls[
|
|
713
|
+
assert.deepEqual(webexLoggerLogCalls[1].args, [
|
|
667
714
|
'call-diagnostic-events -> ',
|
|
668
715
|
'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
|
|
669
716
|
`name: client.alert.displayed`,
|
|
@@ -694,28 +741,28 @@ describe('internal-plugin-metrics', () => {
|
|
|
694
741
|
|
|
695
742
|
const webexLoggerLogCalls = webex.logger.log.getCalls();
|
|
696
743
|
|
|
697
|
-
assert.deepEqual(webexLoggerLogCalls.length,
|
|
744
|
+
assert.deepEqual(webexLoggerLogCalls.length, 4);
|
|
698
745
|
|
|
699
|
-
assert.deepEqual(webexLoggerLogCalls[
|
|
746
|
+
assert.deepEqual(webexLoggerLogCalls[1].args, [
|
|
700
747
|
'call-diagnostic-events -> ',
|
|
701
748
|
'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
|
|
702
749
|
`name: client.alert.displayed`,
|
|
703
750
|
]);
|
|
704
751
|
|
|
705
|
-
assert.deepEqual(webexLoggerLogCalls[
|
|
752
|
+
assert.deepEqual(webexLoggerLogCalls[2].args, [
|
|
706
753
|
'call-diagnostic-events -> ',
|
|
707
754
|
'CallDiagnosticMetrics: @createClientEventObjectInMeeting => collected browser data',
|
|
708
755
|
'{"error":"unable to access window.navigator.userAgent"}',
|
|
709
756
|
]);
|
|
710
757
|
|
|
711
|
-
assert.deepEqual(webexLoggerLogCalls[
|
|
758
|
+
assert.deepEqual(webexLoggerLogCalls[3].args, [
|
|
712
759
|
'call-diagnostic-events -> ',
|
|
713
760
|
'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
|
|
714
761
|
`name: client.alert.displayed`,
|
|
715
762
|
]);
|
|
716
763
|
});
|
|
717
764
|
|
|
718
|
-
it('should submit client event successfully with correlationId, webexConferenceIdStr and globalMeetingId',
|
|
765
|
+
it('should submit client event successfully with correlationId, webexConferenceIdStr and globalMeetingId', () => {
|
|
719
766
|
const prepareDiagnosticEventSpy = sinon.spy(cd, 'prepareDiagnosticEvent');
|
|
720
767
|
const submitToCallDiagnosticsSpy = sinon.spy(cd, 'submitToCallDiagnostics');
|
|
721
768
|
const generateClientEventErrorPayloadSpy = sinon.spy(cd, 'generateClientEventErrorPayload');
|
|
@@ -794,7 +841,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
794
841
|
|
|
795
842
|
const webexLoggerLogCalls = webex.logger.log.getCalls();
|
|
796
843
|
|
|
797
|
-
assert.deepEqual(webexLoggerLogCalls[
|
|
844
|
+
assert.deepEqual(webexLoggerLogCalls[1].args, [
|
|
798
845
|
'call-diagnostic-events -> ',
|
|
799
846
|
'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
|
|
800
847
|
`name: client.alert.displayed`,
|
|
@@ -802,7 +849,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
802
849
|
});
|
|
803
850
|
|
|
804
851
|
it('should submit client event successfully with preLoginId', () => {
|
|
805
|
-
|
|
852
|
+
cd.device.userId = undefined;
|
|
806
853
|
|
|
807
854
|
const prepareDiagnosticEventSpy = sinon.spy(cd, 'prepareDiagnosticEvent');
|
|
808
855
|
const submitToCallDiagnosticsPreLoginSpy = sinon.spy(cd, 'submitToCallDiagnosticsPreLogin');
|
|
@@ -853,11 +900,13 @@ describe('internal-plugin-metrics', () => {
|
|
|
853
900
|
options
|
|
854
901
|
);
|
|
855
902
|
assert.notCalled(submitToCallDiagnosticsSpy);
|
|
856
|
-
assert.calledWith(
|
|
903
|
+
assert.calledWith(
|
|
904
|
+
submitToCallDiagnosticsPreLoginSpy,
|
|
905
|
+
{
|
|
857
906
|
eventId: 'my-fake-id',
|
|
858
907
|
version: 1,
|
|
859
|
-
origin: {
|
|
860
|
-
originTime: {
|
|
908
|
+
origin: {origin: 'fake-origin'},
|
|
909
|
+
originTime: {triggered: now.toISOString(), sent: 'not_defined_yet'},
|
|
861
910
|
senderCountryCode: 'UK',
|
|
862
911
|
event: {
|
|
863
912
|
name: 'client.alert.displayed',
|
|
@@ -869,12 +918,14 @@ describe('internal-plugin-metrics', () => {
|
|
|
869
918
|
orgId: 'orgId',
|
|
870
919
|
locusUrl: 'locus-url',
|
|
871
920
|
webexConferenceIdStr: 'webexConferenceIdStr1',
|
|
872
|
-
globalMeetingId: 'globalMeetingId1'
|
|
921
|
+
globalMeetingId: 'globalMeetingId1',
|
|
873
922
|
},
|
|
874
|
-
eventData: {
|
|
875
|
-
loginType: 'login-ci'
|
|
923
|
+
eventData: {webClientDomain: 'whatever'},
|
|
924
|
+
loginType: 'login-ci',
|
|
876
925
|
},
|
|
877
|
-
|
|
926
|
+
},
|
|
927
|
+
options.preLoginId
|
|
928
|
+
);
|
|
878
929
|
});
|
|
879
930
|
|
|
880
931
|
it('should use meeting loginType if present and meetingId provided', () => {
|
|
@@ -997,13 +1048,13 @@ describe('internal-plugin-metrics', () => {
|
|
|
997
1048
|
});
|
|
998
1049
|
|
|
999
1050
|
const webexLoggerLogCalls = webex.logger.log.getCalls();
|
|
1000
|
-
assert.deepEqual(webexLoggerLogCalls[
|
|
1051
|
+
assert.deepEqual(webexLoggerLogCalls[1].args, [
|
|
1001
1052
|
'call-diagnostic-events -> ',
|
|
1002
1053
|
'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
|
|
1003
1054
|
`name: client.alert.displayed`,
|
|
1004
1055
|
]);
|
|
1005
1056
|
|
|
1006
|
-
assert.deepEqual(webexLoggerLogCalls[
|
|
1057
|
+
assert.deepEqual(webexLoggerLogCalls[2].args, [
|
|
1007
1058
|
'call-diagnostic-events -> ',
|
|
1008
1059
|
'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',
|
|
1009
1060
|
`generatedError: {"fatal":true,"shownToUser":false,"name":"other","category":"expected","errorCode":4029,"serviceErrorCode":2409005,"errorDescription":"StartRecordingFailed"}`,
|
|
@@ -1073,13 +1124,13 @@ describe('internal-plugin-metrics', () => {
|
|
|
1073
1124
|
});
|
|
1074
1125
|
|
|
1075
1126
|
const webexLoggerLogCalls = webex.logger.log.getCalls();
|
|
1076
|
-
assert.deepEqual(webexLoggerLogCalls[
|
|
1127
|
+
assert.deepEqual(webexLoggerLogCalls[1].args, [
|
|
1077
1128
|
'call-diagnostic-events -> ',
|
|
1078
1129
|
'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
|
|
1079
1130
|
`name: client.alert.displayed`,
|
|
1080
1131
|
]);
|
|
1081
1132
|
|
|
1082
|
-
assert.deepEqual(webexLoggerLogCalls[
|
|
1133
|
+
assert.deepEqual(webexLoggerLogCalls[2].args, [
|
|
1083
1134
|
'call-diagnostic-events -> ',
|
|
1084
1135
|
'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',
|
|
1085
1136
|
`generatedError: {"fatal":true,"shownToUser":false,"name":"other","category":"other","errorCode":9999,"serviceErrorCode":9999,"rawErrorMessage":"bad times","errorDescription":"UnknownError"}`,
|
|
@@ -1142,13 +1193,13 @@ describe('internal-plugin-metrics', () => {
|
|
|
1142
1193
|
|
|
1143
1194
|
const webexLoggerLogCalls = webex.logger.log.getCalls();
|
|
1144
1195
|
|
|
1145
|
-
assert.deepEqual(webexLoggerLogCalls[
|
|
1196
|
+
assert.deepEqual(webexLoggerLogCalls[1].args, [
|
|
1146
1197
|
'call-diagnostic-events -> ',
|
|
1147
1198
|
'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
|
|
1148
1199
|
`name: client.alert.displayed`,
|
|
1149
1200
|
]);
|
|
1150
1201
|
|
|
1151
|
-
assert.deepEqual(webexLoggerLogCalls[
|
|
1202
|
+
assert.deepEqual(webexLoggerLogCalls[2].args, [
|
|
1152
1203
|
'call-diagnostic-events -> ',
|
|
1153
1204
|
'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',
|
|
1154
1205
|
`generatedError: {"fatal":true,"shownToUser":false,"name":"other","category":"other","errorCode":9999,"serviceErrorCode":9999,"rawErrorMessage":"bad times","errorDescription":"UnknownError"}`,
|
|
@@ -1215,13 +1266,13 @@ describe('internal-plugin-metrics', () => {
|
|
|
1215
1266
|
|
|
1216
1267
|
const webexLoggerLogCalls = webex.logger.log.getCalls();
|
|
1217
1268
|
|
|
1218
|
-
assert.deepEqual(webexLoggerLogCalls[
|
|
1269
|
+
assert.deepEqual(webexLoggerLogCalls[1].args, [
|
|
1219
1270
|
'call-diagnostic-events -> ',
|
|
1220
1271
|
'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',
|
|
1221
1272
|
`name: client.alert.displayed`,
|
|
1222
1273
|
]);
|
|
1223
1274
|
|
|
1224
|
-
assert.deepEqual(webexLoggerLogCalls[
|
|
1275
|
+
assert.deepEqual(webexLoggerLogCalls[2].args, [
|
|
1225
1276
|
'call-diagnostic-events -> ',
|
|
1226
1277
|
'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',
|
|
1227
1278
|
`generatedError: {"fatal":true,"shownToUser":false,"name":"other","category":"expected","errorCode":4029,"serviceErrorCode":2409005,"errorDescription":"StartRecordingFailed"}`,
|
|
@@ -1339,7 +1390,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
1339
1390
|
});
|
|
1340
1391
|
});
|
|
1341
1392
|
|
|
1342
|
-
describe(
|
|
1393
|
+
describe('#submitToCallDiagnostics', () => {
|
|
1343
1394
|
it('should send request to call diagnostic batcher', () => {
|
|
1344
1395
|
const requestStub = sinon.stub();
|
|
1345
1396
|
//@ts-ignore
|
|
@@ -1348,7 +1399,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
1348
1399
|
cd.submitToCallDiagnostics({event: 'test'});
|
|
1349
1400
|
assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
|
|
1350
1401
|
});
|
|
1351
|
-
})
|
|
1402
|
+
});
|
|
1352
1403
|
|
|
1353
1404
|
describe('#submitMQE', () => {
|
|
1354
1405
|
it('submits the event correctly', () => {
|
|
@@ -1402,6 +1453,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
1402
1453
|
},
|
|
1403
1454
|
eventData: {webClientDomain: 'whatever'},
|
|
1404
1455
|
intervals: [{}],
|
|
1456
|
+
callingServiceType: 'LOCUS',
|
|
1405
1457
|
sourceMetadata: {
|
|
1406
1458
|
applicationSoftwareType: 'webex-js-sdk',
|
|
1407
1459
|
applicationSoftwareVersion: 'webex-version',
|
|
@@ -1437,6 +1489,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
1437
1489
|
},
|
|
1438
1490
|
eventData: {webClientDomain: 'whatever'},
|
|
1439
1491
|
intervals: [{}],
|
|
1492
|
+
callingServiceType: 'LOCUS',
|
|
1440
1493
|
sourceMetadata: {
|
|
1441
1494
|
applicationSoftwareType: 'webex-js-sdk',
|
|
1442
1495
|
applicationSoftwareVersion: 'webex-version',
|
|
@@ -1470,6 +1523,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
1470
1523
|
},
|
|
1471
1524
|
eventData: {webClientDomain: 'whatever'},
|
|
1472
1525
|
intervals: [{}],
|
|
1526
|
+
callingServiceType: 'LOCUS',
|
|
1473
1527
|
sourceMetadata: {
|
|
1474
1528
|
applicationSoftwareType: 'webex-js-sdk',
|
|
1475
1529
|
applicationSoftwareVersion: 'webex-version',
|
|
@@ -1801,6 +1855,27 @@ describe('internal-plugin-metrics', () => {
|
|
|
1801
1855
|
});
|
|
1802
1856
|
});
|
|
1803
1857
|
|
|
1858
|
+
it('should override custom properties for an unknown error', () => {
|
|
1859
|
+
const error = new Error('bad times');
|
|
1860
|
+
|
|
1861
|
+
(error as any).payloadOverrides = {
|
|
1862
|
+
shownToUser: true,
|
|
1863
|
+
category: 'expected',
|
|
1864
|
+
};
|
|
1865
|
+
|
|
1866
|
+
const res = cd.generateClientEventErrorPayload(error);
|
|
1867
|
+
assert.deepEqual(res, {
|
|
1868
|
+
category: 'expected',
|
|
1869
|
+
errorDescription: 'UnknownError',
|
|
1870
|
+
fatal: true,
|
|
1871
|
+
name: 'other',
|
|
1872
|
+
shownToUser: true,
|
|
1873
|
+
serviceErrorCode: 9999,
|
|
1874
|
+
errorCode: 9999,
|
|
1875
|
+
rawErrorMessage: 'bad times',
|
|
1876
|
+
});
|
|
1877
|
+
});
|
|
1878
|
+
|
|
1804
1879
|
it('should override custom properties for a NetworkOrCORSError', () => {
|
|
1805
1880
|
const error = new WebexHttpError.NetworkOrCORSError({
|
|
1806
1881
|
url: 'https://example.com',
|
|
@@ -1942,12 +2017,16 @@ describe('internal-plugin-metrics', () => {
|
|
|
1942
2017
|
|
|
1943
2018
|
describe('httpStatusCode', () => {
|
|
1944
2019
|
it('should include httpStatusCode for browser media errors', () => {
|
|
1945
|
-
const res = cd.generateClientEventErrorPayload({
|
|
2020
|
+
const res = cd.generateClientEventErrorPayload({
|
|
2021
|
+
name: 'PermissionDeniedError',
|
|
2022
|
+
message: 'bad times',
|
|
2023
|
+
statusCode: 401,
|
|
2024
|
+
});
|
|
1946
2025
|
assert.deepEqual(res, {
|
|
1947
2026
|
category: 'expected',
|
|
1948
2027
|
errorCode: 4032,
|
|
1949
2028
|
errorData: {
|
|
1950
|
-
errorName: 'PermissionDeniedError'
|
|
2029
|
+
errorName: 'PermissionDeniedError',
|
|
1951
2030
|
},
|
|
1952
2031
|
errorDescription: 'CameraPermissionDenied',
|
|
1953
2032
|
fatal: true,
|
|
@@ -1960,12 +2039,16 @@ describe('internal-plugin-metrics', () => {
|
|
|
1960
2039
|
});
|
|
1961
2040
|
|
|
1962
2041
|
it('should include httpStatusCode for SdpOfferCreationErrors', () => {
|
|
1963
|
-
const res = cd.generateClientEventErrorPayload({
|
|
2042
|
+
const res = cd.generateClientEventErrorPayload({
|
|
2043
|
+
name: 'SdpOfferCreationError',
|
|
2044
|
+
message: 'bad times',
|
|
2045
|
+
statusCode: 404,
|
|
2046
|
+
});
|
|
1964
2047
|
assert.deepEqual(res, {
|
|
1965
2048
|
category: 'media',
|
|
1966
2049
|
errorCode: 2050,
|
|
1967
2050
|
errorData: {
|
|
1968
|
-
errorName: 'SdpOfferCreationError'
|
|
2051
|
+
errorName: 'SdpOfferCreationError',
|
|
1969
2052
|
},
|
|
1970
2053
|
errorDescription: 'SdpOfferCreationError',
|
|
1971
2054
|
fatal: true,
|
|
@@ -1978,7 +2061,11 @@ describe('internal-plugin-metrics', () => {
|
|
|
1978
2061
|
});
|
|
1979
2062
|
|
|
1980
2063
|
it('should include httpStatusCode for service error codes', () => {
|
|
1981
|
-
const res = cd.generateClientEventErrorPayload({
|
|
2064
|
+
const res = cd.generateClientEventErrorPayload({
|
|
2065
|
+
body: {errorCode: 58400},
|
|
2066
|
+
message: 'bad times',
|
|
2067
|
+
statusCode: 400,
|
|
2068
|
+
});
|
|
1982
2069
|
assert.deepEqual(res, {
|
|
1983
2070
|
category: 'signaling',
|
|
1984
2071
|
errorCode: 4100,
|
|
@@ -1993,7 +2080,11 @@ describe('internal-plugin-metrics', () => {
|
|
|
1993
2080
|
});
|
|
1994
2081
|
|
|
1995
2082
|
it('should include httpStatusCode for locus service error codes', () => {
|
|
1996
|
-
const res = cd.generateClientEventErrorPayload({
|
|
2083
|
+
const res = cd.generateClientEventErrorPayload({
|
|
2084
|
+
body: {errorCode: 2403001},
|
|
2085
|
+
message: 'bad times',
|
|
2086
|
+
statusCode: 400,
|
|
2087
|
+
});
|
|
1997
2088
|
assert.deepEqual(res, {
|
|
1998
2089
|
category: 'expected',
|
|
1999
2090
|
errorCode: 3007,
|
|
@@ -2008,7 +2099,11 @@ describe('internal-plugin-metrics', () => {
|
|
|
2008
2099
|
});
|
|
2009
2100
|
|
|
2010
2101
|
it('should include httpStatusCode for meetingInfo service error codes', () => {
|
|
2011
|
-
const res = cd.generateClientEventErrorPayload({
|
|
2102
|
+
const res = cd.generateClientEventErrorPayload({
|
|
2103
|
+
body: {data: {meetingInfo: {}}},
|
|
2104
|
+
message: 'bad times',
|
|
2105
|
+
statusCode: 400,
|
|
2106
|
+
});
|
|
2012
2107
|
assert.deepEqual(res, {
|
|
2013
2108
|
category: 'signaling',
|
|
2014
2109
|
errorCode: 4100,
|
|
@@ -2023,8 +2118,10 @@ describe('internal-plugin-metrics', () => {
|
|
|
2023
2118
|
});
|
|
2024
2119
|
|
|
2025
2120
|
it('should include httpStatusCode for network errors', () => {
|
|
2026
|
-
const error = new WebexHttpError.NetworkOrCORSError(
|
|
2027
|
-
|
|
2121
|
+
const error = new WebexHttpError.NetworkOrCORSError({
|
|
2122
|
+
statusCode: 400,
|
|
2123
|
+
options: {service: '', headers: {}},
|
|
2124
|
+
});
|
|
2028
2125
|
const res = cd.generateClientEventErrorPayload(error);
|
|
2029
2126
|
assert.deepEqual(res, {
|
|
2030
2127
|
category: 'network',
|
|
@@ -2040,8 +2137,10 @@ describe('internal-plugin-metrics', () => {
|
|
|
2040
2137
|
});
|
|
2041
2138
|
|
|
2042
2139
|
it('should include httpStatusCode for unauthorized errors', () => {
|
|
2043
|
-
const error = new WebexHttpError.Unauthorized(
|
|
2044
|
-
|
|
2140
|
+
const error = new WebexHttpError.Unauthorized({
|
|
2141
|
+
statusCode: 401,
|
|
2142
|
+
options: {service: '', headers: {}},
|
|
2143
|
+
});
|
|
2045
2144
|
const res = cd.generateClientEventErrorPayload(error);
|
|
2046
2145
|
assert.deepEqual(res, {
|
|
2047
2146
|
category: 'network',
|
|
@@ -2235,7 +2334,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
2235
2334
|
|
|
2236
2335
|
const webexLoggerLogCalls = webex.logger.log.getCalls();
|
|
2237
2336
|
|
|
2238
|
-
assert.deepEqual(webexLoggerLogCalls[
|
|
2337
|
+
assert.deepEqual(webexLoggerLogCalls[1].args, [
|
|
2239
2338
|
'call-diagnostic-events -> ',
|
|
2240
2339
|
'CallDiagnosticMetrics: @buildClientEventFetchRequestOptions. Building request options object for fetch()...',
|
|
2241
2340
|
`name: client.exit.app`,
|
|
@@ -2244,7 +2343,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
2244
2343
|
});
|
|
2245
2344
|
});
|
|
2246
2345
|
|
|
2247
|
-
describe(
|
|
2346
|
+
describe('#submitToCallDiagnosticsPreLogin', () => {
|
|
2248
2347
|
it('should send request to call diagnostic batcher and saves preLoginId', () => {
|
|
2249
2348
|
const requestStub = sinon.stub();
|
|
2250
2349
|
//@ts-ignore
|
|
@@ -2257,7 +2356,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
2257
2356
|
assert.calledWith(cd.preLoginMetricsBatcher.savePreLoginId, preLoginId);
|
|
2258
2357
|
assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
|
|
2259
2358
|
});
|
|
2260
|
-
})
|
|
2359
|
+
});
|
|
2261
2360
|
|
|
2262
2361
|
describe('#isServiceErrorExpected', () => {
|
|
2263
2362
|
it('returns true for code mapped to "expected"', () => {
|
|
@@ -2272,5 +2371,20 @@ describe('internal-plugin-metrics', () => {
|
|
|
2272
2371
|
assert.isFalse(cd.isServiceErrorExpected(999999));
|
|
2273
2372
|
});
|
|
2274
2373
|
});
|
|
2374
|
+
|
|
2375
|
+
describe('#setDeviceInfo', () => {
|
|
2376
|
+
// The method is called in beforeEach itself. We are just testing it here
|
|
2377
|
+
it('sets the received deviceInfo to call-diagnostics', () => {
|
|
2378
|
+
const webexLoggerLogCalls = webex.logger.log.getCalls();
|
|
2379
|
+
const device = { userId: 'userId', url: 'deviceUrl', orgId: 'orgId' };
|
|
2380
|
+
|
|
2381
|
+
assert.deepEqual(webexLoggerLogCalls[0].args, [
|
|
2382
|
+
'CallDiagnosticMetrics: @setDeviceInfo called',
|
|
2383
|
+
device
|
|
2384
|
+
]);
|
|
2385
|
+
|
|
2386
|
+
assert.deepEqual(cd.device, device);
|
|
2387
|
+
});
|
|
2388
|
+
});
|
|
2275
2389
|
});
|
|
2276
2390
|
});
|
|
@@ -301,17 +301,31 @@ describe('internal-plugin-metrics', () => {
|
|
|
301
301
|
|
|
302
302
|
[
|
|
303
303
|
['client.exit.app', {}],
|
|
304
|
-
[
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
304
|
+
[
|
|
305
|
+
'client.login.end',
|
|
306
|
+
{
|
|
307
|
+
joinTimes: {
|
|
308
|
+
otherAppApiReqResp: undefined,
|
|
309
|
+
exchangeCITokenJMT: undefined,
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
[
|
|
314
|
+
'client.webexapp.launched',
|
|
315
|
+
{
|
|
316
|
+
joinTimes: {
|
|
317
|
+
downloadTime: undefined,
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
],
|
|
309
321
|
[
|
|
310
322
|
'client.interstitial-window.launched',
|
|
311
323
|
{
|
|
312
324
|
joinTimes: {
|
|
313
325
|
clickToInterstitial: undefined,
|
|
314
326
|
meetingInfoReqResp: undefined,
|
|
327
|
+
refreshCaptchaServiceReqResp: undefined,
|
|
328
|
+
downloadIntelligenceModelsReqResp: undefined,
|
|
315
329
|
},
|
|
316
330
|
},
|
|
317
331
|
],
|
|
@@ -322,6 +336,8 @@ describe('internal-plugin-metrics', () => {
|
|
|
322
336
|
showInterstitialTime: undefined,
|
|
323
337
|
meetingInfoReqResp: undefined,
|
|
324
338
|
registerWDMDeviceJMT: undefined,
|
|
339
|
+
getU2CTime: undefined,
|
|
340
|
+
getReachabilityClustersReqResp: undefined,
|
|
325
341
|
},
|
|
326
342
|
},
|
|
327
343
|
],
|
|
@@ -332,13 +348,12 @@ describe('internal-plugin-metrics', () => {
|
|
|
332
348
|
meetingInfoReqResp: undefined,
|
|
333
349
|
callInitJoinReq: undefined,
|
|
334
350
|
joinReqResp: undefined,
|
|
335
|
-
joinReqSentReceived: undefined,
|
|
336
351
|
pageJmt: undefined,
|
|
337
352
|
clickToInterstitial: undefined,
|
|
338
353
|
interstitialToJoinOK: undefined,
|
|
339
354
|
totalJmt: undefined,
|
|
340
355
|
clientJmt: undefined,
|
|
341
|
-
downloadTime: undefined
|
|
356
|
+
downloadTime: undefined,
|
|
342
357
|
},
|
|
343
358
|
},
|
|
344
359
|
],
|
|
@@ -600,6 +615,12 @@ describe('internal-plugin-metrics', () => {
|
|
|
600
615
|
turnServerUsed: true,
|
|
601
616
|
errorCode: DTLS_HANDSHAKE_FAILED_CLIENT_CODE,
|
|
602
617
|
},
|
|
618
|
+
{
|
|
619
|
+
signalingState: 'stable',
|
|
620
|
+
iceConnectionState: 'disconnected',
|
|
621
|
+
turnServerUsed: true,
|
|
622
|
+
errorCode: DTLS_HANDSHAKE_FAILED_CLIENT_CODE,
|
|
623
|
+
},
|
|
603
624
|
{
|
|
604
625
|
signalingState: 'stable',
|
|
605
626
|
iceConnectionState: 'failed',
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {assert} from '@webex/test-helper-chai';
|
|
6
|
+
import MockWebex from '@webex/test-helper-mock-webex';
|
|
7
|
+
import sinon from 'sinon';
|
|
8
|
+
import Metrics from '@webex/internal-plugin-metrics';
|
|
9
|
+
import PreLoginMetricsBatcher from '@webex/internal-plugin-metrics';
|
|
10
|
+
import ClientMetricsPreloginBatcher from '@webex/internal-plugin-metrics';
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
describe('internal-plugin-metrics', () => {
|
|
14
|
+
describe('ClientMetricsPreloginBatcher', () => {
|
|
15
|
+
let webex;
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
//@ts-ignore
|
|
19
|
+
webex = new MockWebex({
|
|
20
|
+
children: {
|
|
21
|
+
metrics: Metrics,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
webex.request = (options) =>
|
|
26
|
+
Promise.resolve({body: {items: []}, waitForServiceTimeout: 15, options});
|
|
27
|
+
|
|
28
|
+
sinon.spy(webex, 'request');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
sinon.restore();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should be an instance of PreLoginMetricsBatcher', () => {
|
|
36
|
+
const clientMetricsPreloginBatcher = new ClientMetricsPreloginBatcher();
|
|
37
|
+
assert.instanceOf(clientMetricsPreloginBatcher, PreLoginMetricsBatcher);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
it('checks prepareItem', async () => {
|
|
42
|
+
const testItem = {id: 1};
|
|
43
|
+
const resultPromise = await webex.internal.metrics.clientMetricsPreloginBatcher.prepareItem(testItem);
|
|
44
|
+
assert.strictEqual(resultPromise, testItem);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('checks prepareRequest', async () => {
|
|
48
|
+
const testQueue = [];
|
|
49
|
+
|
|
50
|
+
const resultPromise = await webex.internal.metrics.clientMetricsPreloginBatcher.prepareRequest(testQueue);
|
|
51
|
+
assert.strictEqual(resultPromise, testQueue);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -104,9 +104,15 @@ describe('plugin-metrics', () => {
|
|
|
104
104
|
};
|
|
105
105
|
webex.config.metrics.type = ['operational'];
|
|
106
106
|
webex.config.metrics.appType = 'sdk';
|
|
107
|
+
webex.meetings = {
|
|
108
|
+
config: {
|
|
109
|
+
metrics: {
|
|
110
|
+
clientVersion: '43.0.105'
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
107
114
|
|
|
108
115
|
sinon.spy(webex, 'request');
|
|
109
|
-
sinon.spy(metrics, 'postPreLoginMetric');
|
|
110
116
|
sinon.spy(metrics, 'aliasUser');
|
|
111
117
|
});
|
|
112
118
|
|
|
@@ -180,6 +186,7 @@ describe('plugin-metrics', () => {
|
|
|
180
186
|
},
|
|
181
187
|
metricName: 'test',
|
|
182
188
|
tags: {
|
|
189
|
+
appVersion: '43.0.105',
|
|
183
190
|
browser: '',
|
|
184
191
|
domain: 'whatever',
|
|
185
192
|
os: 'other',
|
|
@@ -199,7 +206,7 @@ describe('plugin-metrics', () => {
|
|
|
199
206
|
|
|
200
207
|
describe('#submitClientMetrics()', () => {
|
|
201
208
|
describe('before login', () => {
|
|
202
|
-
it('
|
|
209
|
+
it('clientMetricsPreloginBatcher pre-login metric', () => {
|
|
203
210
|
const date = clock.now;
|
|
204
211
|
const promise = metrics.submitClientMetrics(eventName, mockPayload, preLoginId);
|
|
205
212
|
|
|
@@ -207,8 +214,6 @@ describe('plugin-metrics', () => {
|
|
|
207
214
|
.then(() => clock.tick(config.metrics.batcherWait))
|
|
208
215
|
.then(() => promise)
|
|
209
216
|
.then(() => {
|
|
210
|
-
assert.called(metrics.postPreLoginMetric);
|
|
211
|
-
assert.calledOnce(webex.credentials.getClientToken);
|
|
212
217
|
assert.calledOnce(webex.request);
|
|
213
218
|
const req = webex.request.args[0][0];
|
|
214
219
|
const metric = req.body.metrics[0];
|
|
@@ -296,33 +301,6 @@ describe('plugin-metrics', () => {
|
|
|
296
301
|
});
|
|
297
302
|
});
|
|
298
303
|
|
|
299
|
-
describe('#postPreLoginMetric()', () => {
|
|
300
|
-
it('returns an HttpResponse object', () => {
|
|
301
|
-
const promise = metrics.postPreLoginMetric(preLoginProps, preLoginId);
|
|
302
|
-
|
|
303
|
-
return promiseTick(50)
|
|
304
|
-
.then(() => clock.tick(config.metrics.batcherWait))
|
|
305
|
-
.then(() => promise)
|
|
306
|
-
.then(() => {
|
|
307
|
-
assert.calledOnce(webex.request);
|
|
308
|
-
const req = webex.request.args[0][0];
|
|
309
|
-
const metric = req.body.metrics[0];
|
|
310
|
-
const {headers} = req;
|
|
311
|
-
|
|
312
|
-
assert.property(headers, 'x-prelogin-userid');
|
|
313
|
-
assert.property(metric, 'metricName');
|
|
314
|
-
assert.property(metric, 'tags');
|
|
315
|
-
assert.property(metric, 'fields');
|
|
316
|
-
assert.property(metric, 'timestamp');
|
|
317
|
-
|
|
318
|
-
assert.equal(metric.timestamp, transformedProps.timestamp);
|
|
319
|
-
assert.equal(metric.metricName, eventName);
|
|
320
|
-
assert.equal(metric.tags.testTag, 'tag value');
|
|
321
|
-
assert.equal(metric.fields.testField, 123);
|
|
322
|
-
});
|
|
323
|
-
});
|
|
324
|
-
});
|
|
325
|
-
|
|
326
304
|
describe('#aliasUser()', () => {
|
|
327
305
|
it('returns an HttpResponse object', () =>
|
|
328
306
|
metrics.aliasUser(preLoginId).then(() => {
|